这是this one的后续问题。
举个简单的例子:
public class Main
{
public static void main(String[] args) throws Exception
{
Runtime.getRuntime().exec("./child");
// This is just so that the JVM does not exit
Thread.sleep(1000 * 1000);
}
}
这是孩子的过程:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
void handle_sigquit(int sig) {
printf("Signal %d received\n", sig);
exit(1);
}
int main(int argc, char **argv) {
signal(SIGQUIT, &handle_sigquit);
sleep(1000);
}
如您所见,我在子进程中明确设置了一个信号处理程序。
当我从shell运行此进程时,我可以发送一个SIGQUIT
;信号被正确接收和处理。但是,如果我从Java启动该过程(我在Linux上使用openjdk6),则不会传递信号。这是为什么?
答案 0 :(得分:2)
java(OpenJDK 6)默认阻止子进程中的SIGQUIT。阻塞的信号在fork和exec之间仍然被阻塞。您可以通过查看子进程的procfs状态文件在Linux上看到此信息:
$ grep Sig /proc/11246/status
SigPnd: 0000000000000000
SigBlk: 0000000000000004
SigIgn: 0000000000000000
SigCgt: 0000000000000000
您可以使用以下命令在非线程进程中取消阻止SIGQUIT:
sigemptyset(&set);
sigaddset(&set, SIGQUIT);
sigprocmask(SIG_UNBLOCK, &set, NULL);
请注意,您的printfs不会出现在终端窗口中; java将用管道替换子进程的stdin,stdout和stderr,并读取进程的stdout,你会做类似的事情
Process p=Runtime.getRuntime().exec("./child");
InputStream stdout = p.getInputStream();