簡體   English   中英

如果使用了waitFor,為什么殺死JVM也會終止其子進程?

[英]Why does killing JVM also terminates its child process if waitFor has been used?

如果不使用waitFor ,則終止JVM對其子進程沒有影響。 這是一個例子。

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 ps -ef | grep 'child.sh' | grep -v grep ps -ef | grep 'child.sh' | grep -v grep顯示:

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,它沒有解釋此行為。 然后,我使用以下代碼檢查forkexeclpwaitpid系統調用的行為。 它顯示了相同的行為。

#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

誰能解釋一下waitForwaitpid這種作用?

Process.waitFor()是否使進程依賴於Java父級? 在MAC平台上問類似的問題。 但是它缺少細節。 所以我在這里針對我的環境提出這個問題。

除了將父進程保持在前台這一事實之外, waitPid()沒有什么特別的。


如果分叉,然后等待子進程完成,則將有一個(簡化的)進程樹,如下所示:

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

java是終端中的前台進程,而子進程位於其進程組中。

當您按^ C時, 整個前台進程組將終止 1個


如果你等待,然后在第一你的進程樹是一樣的,如上圖所示。 java進程終止,並且子進程成為進程樹根目錄處的子進程。

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

子進程完成執行並正常終止。


1進程組收到一個SIGINT,其默認操作為終止。 但是,可能會安裝其他信號處理程序。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM