如果waitFor未使用,则终止JVM对其子进程没有影响。这是一个例子。
waitFor
Bash脚本:
#!/usr/bin/env bash echo "Sleeping..." > 'log' sleep 30 echo "Wake up" >> 'log'
Java代码:
public class Code { public static void main(String[] args) throws Exception { Process process = Runtime.getRuntime().exec("./child.sh"); // process.waitFor(); } }
后Java Code发出后,JVM立即终止。并ps -ef | grep 'child.sh' | grep -v grep显示:
Java Code
ps -ef | grep 'child.sh' | grep -v grep
jing 3535 2761 0 13:47 pts/15 00:00:00 bash ./child.sh
然后30秒后,我检查log当前目录中文件的内容。内容是:
log
Sleeping... Wake up
上面的grep命令现在什么也没显示。现在我取消注释process.waitFor()并重新编译Code.java。运行之后java Code,我使用上面的grep命令来验证child.sh子进程正在运行。然后我发出Ctrl-CJVM终止。现在,运行上面的grep命令不会显示任何内容。log文件内容保持为:
grep
process.waitFor()
Code.java
java Code
child.sh
Ctrl-C
Sleeping...
我已经检查了Process不能解释此行为的Javadoc。然后我用下面的代码来检查的行为fork,execlp以及 waitpid系统调用。它显示了相同的行为。
Process
fork
execlp
waitpid
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/wait.h> static void err_sys(const char* msg) { printf("%s\n", msg); exit(1); } int main(void) { pid_t pid; if ((pid = fork()) < 0) { err_sys("fork error"); } else if (pid == 0) { if (execlp("/home/jing/code/lintcode/child.sh", "child.sh", (char *)0) < 0) err_sys("execlp error"); } if (waitpid(pid, NULL, 0) < 0) err_sys("wait error"); exit(0); }
我在Ubuntu 14.04上使用Oracle JDK 1.8。uname -a产生:
uname -a
Linux jinglin 3.13.0-108-generic #155-Ubuntu SMP Wed Jan 11 16:58:52 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
谁能解释waitFor和的这种影响waitpid?
Process.waitFor()是否使进程依赖于Java父级?在MAC平台上问类似的问题。但是它缺少细节。所以我在这里针对我的环境提出这个问题。
除了waitPid()您将父进程放在前台这一事实之外,没有什么特别的。
waitPid()
如果分叉,然后等待子进程完成,则将有一个(简化的)进程树,如下所示:
─┬= 1 init └─┬= 2 bash --login └─┬= 3 java code └─── 4 bash child.sh
java 是终端中的前台进程,子进程位于其进程组中。
java
当您按^ C时, 整个前台进程组将终止 。1个
如果你 不 等待,然后在第一你的进程树是一样的,如上图所示。该java过程终止,子进程在进程树的根成为进程的子。
─┬= 1 init ├──= 2 bash --login └─── 4 bash child.sh
子进程完成执行并正常终止。
1进程组收到一个SIGINT,其默认操作将终止。但是,可能会安装其他信号处理程序。