如果使用了 waitFor,为什么杀死 JVM 也会终止其子进程?

2024-03-17

If waitFor不使用时,杀死JVM对其子进程没有影响。这是一个例子。

重击脚本:

#!/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();
  }
}

After Java Code发出后,JVM 立即终止。和ps -ef | grep 'child.sh' | grep -v grep shows:

jing      3535  2761  0 13:47 pts/15   00:00:00 bash ./child.sh

然后30秒后,我检查了内容log当前目录中的文件。内容是:

Sleeping...
Wake up

还有上面的grep命令现在什么也不显示。现在我取消评论process.waitFor()并重新编译Code.java。我跑完之后java Code,我用上面的grep命令来验证child.sh子进程正在运行。然后我发出Ctrl-C,JVM 终止。现在运行上面的grep命令没有显示任何内容。以及内容log文件保持为:

Sleeping...

我检查过Process的 Javadoc 没有解释这种行为。然后我使用以下代码来检查的行为fork , execlp and 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产生:

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 and waitpid?

Process.waitFor() 是否使进程依赖于 java 父进程? https://stackoverflow.com/q/29796031/431698在MAC平台上问类似的问题。但它缺乏细节。所以我针对我这里的环境问这个问题。


没什么特别的waitPid(),除了将父进程保留在前台这一事实之外。


如果您分叉然后等待子进程完成,您将得到一个(简化的)进程树,如下所示:

─┬= 1 init
 └─┬= 2 bash --login
   └─┬= 3 java code
     └─── 4 bash child.sh

java是终端中的前台进程,子进程位于其进程组中。

When you hit ^C the entire foreground process group gets terminated.1


If you don't等等,那么一开始你的进程树就和上面的一样了。这java进程终止,子进程成为进程树根进程的子进程。

─┬= 1 init
 ├──= 2 bash --login
 └─── 4 bash child.sh

子进程执行完毕并正常终止。


1The process group receives a SIGINT, for which the default action is to terminate. However, a different signal handler may be installed.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如果使用了 waitFor,为什么杀死 JVM 也会终止其子进程? 的相关文章

随机推荐