如果使用waitFor,为什么kill JVM也会终止其子进程? [英] Why does killing JVM also terminates its child process if waitFor has been used?

查看:169
本文介绍了如果使用waitFor,为什么kill JVM也会终止其子进程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果未使用 waitFor ,则终止JVM对其子进程没有影响。这是一个例子。

If waitFor is not used, killing JVM has no effect on its child process. Here is an example.

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代码,JVM立即终止。并且 ps -ef | grep'child.sh'| grep -v grep 显示:

After Java Code is issued, JVM terminates immediately. And ps -ef | grep 'child.sh' | grep -v grep shows:

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

然后在30秒后检查<$ c的内容$ c> log 当前目录中的文件。内容为:

Then after 30 seconds, I check the content of log file in the current directory. The content is:

Sleeping...
Wake up

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

And the above grep command shows nothing now. Now I uncomment process.waitFor() and recompile Code.java. After I run java Code, I use the above grep command to verify that child.sh child process is running. Then I issue Ctrl-C, JVM terminates. Now running the above grep command shows nothing. And the content of log file stays as:

Sleeping...

我检查了处理的Javadoc没有解释这种行为。然后我使用以下代码检查 fork execlp waitpid 系统调用。它显示了相同的行为。

I have checked Process's Javadoc which does not explain this behavior. Then I use the following code to check the behavior of fork , execlp and waitpid system calls. And it shows the same behavior.

#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 产生:

I am using Oracle JDK 1.8 on Ubuntu 14.04. uname -a produces:

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 的影响吗?

Can anyone give an explanation about this effect of waitFor and waitpid?

Process.waitFor()是否使进程依赖于java父级?在MAC上提出类似的问题平台。但它缺乏细节。所以我在这里向我的环境提出这个问题。

Does Process.waitFor() make the process reliant on the java parent? asks a similar problem on MAC platform. But it lacks details. So I ask this question for my environment here.

推荐答案

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

There's nothing special about waitPid(), other than the fact that you keep the parent process in the foreground.

如果你分叉和然后等待孩子完成,你有一个(简化的)过程树,如下所示:

If you fork and then wait for the child to finish, you have a (simplified) process tree like this:

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

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

java is the foreground process in the terminal and the child is in its process group.

当你点击^ C时,整个前台进程组被终止 1

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

如果等待,那么首先您的进程树与上面的进程树相同。 java 进程终止,子进程成为进程树根处的进程的子进程。

If you don't wait, then at first your process tree is the same as the one above. The java process terminates and the child process becomes a child of the process at the root of the process tree.

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

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

The child process finishes executing and terminates normally.

1 进程组收到一个SIGINT,默认操作将终止。但是,可以安装不同的信号处理程序。

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

这篇关于如果使用waitFor,为什么kill JVM也会终止其子进程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆