Path: csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!feeder.erje.net!eu.feeder.erje.net!eternal-september.org!feeder.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Eric Sosman Newsgroups: comp.lang.java.programmer Subject: Re: a question about using ProcessBuilder to call external command Date: Wed, 12 Mar 2014 16:36:33 -0400 Organization: A noiseless patient Spider Lines: 46 Message-ID: References: <8f4aa46a-16f4-4b36-a951-7e8eda1692db@googlegroups.com> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Injection-Date: Wed, 12 Mar 2014 20:36:31 +0000 (UTC) Injection-Info: mx05.eternal-september.org; posting-host="bd4e1cba8d8592bec5d5ed9e4537fbfd"; logging-data="10660"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX189bqgRZ7eRcZuAneTLKXk1" User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:24.0) Gecko/20100101 Thunderbird/24.3.0 In-Reply-To: <8f4aa46a-16f4-4b36-a951-7e8eda1692db@googlegroups.com> Cancel-Lock: sha1:w7jHdltVR2hLDbSY/WB9m3sTHV8= Xref: csiph.com comp.lang.java.programmer:27745 On 3/12/2014 4:06 PM, zyng wrote: > Hi: > > I am using the following code to call a system command > > final ProcessBuilder processBuilder = new ProcessBuilder(new String[]{"/bin/sh", "-c", the_command_and_arguments}); > > final Process processRunSysCmd = processBuilder.start();//start a new process -- a child process > > > I have learned that I need to drain the output of the external command (input stream to the parent process -- the java program) in case that it has too much output and the buffer is saturated. In that case, the program will hang. The details vary from one operating system to another, but yes: The amount of output that can be held "in transit" waiting to be read is usually limited, and may be rather small. If the writing process fills that output buffer faster than the reading process drains it, the writer will eventually need to wait for the reader to make some progress. And if the reader's progress rate is zero, the writer may need to wait for a v-e-r-y l-o-n-g t-i-m-e. > But when I think deeper, I am puzzled: there are two processes running now(one is the one i called "parent process", another is the child process). Since each one is single threaded, may I say there are two threads right now?! Yes, or better "At least three, and probably more." The parent process, written in Java and running on the JVM, is almost certainly *not* single-threaded (think garbage collector threads, finalizer threads, ...) But even if the JVM were single-threaded, you'd then have a child process running "/bin/sh" (at least one thread) and probably a grandchild process running "the_command_and_arguments" (at least one thread), and maybe great-grandchildren and further descendants. > So if I don't drain the output of the child process, and too much output and buffer saturated, the parent process will hang?! Will the child process hang too? Or both processes hang? Since they are two threads, so one thread cause another thread hang? I think you've got it backwards: The *writer* will hang when its buffer fills, but the *reader* isn't impeded. For all the system knows, the (non-)reader may be doing some housekeeping before getting ready to read what the writer wrote. If you don't care about the output from the child/grandchild/... processes, an alternative to draining and discarding it may be to have it written to a sinkhole destination like "/dev/null" instead of to a pipe or socket or other IPC channel. -- Eric Sosman esosman@comcast-dot-net.invalid