[英]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,它沒有解釋此行為。 然后,我使用以下代碼檢查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
產生:
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()
沒有什么特別的。
如果分叉,然后等待子進程完成,則將有一個(簡化的)進程樹,如下所示:
─┬= 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.