举个简单的例子:
public class Main
{
public static void main(String[] args) throws Exception
{
Runtime.getRuntime().exec("sleep 1000");
// This is just so that the JVM does not exit
Thread.sleep(1000 * 1000);
}
}
我使用openjdk6在Linux上运行它。如果我尝试向“睡眠”过程发送SIGQUIT
信号,它会忽略它。其他信号(SIGINT
,SIGTERM
等)都可以正常工作,但SIGQUIT
会被忽略。如果我只是在不使用Java的情况下从shell运行sleep 1000
,那么SIGQUIT
将得到正确处理。
为什么行为不同?
答案 0 :(得分:4)
将-Xrs
选项传递给java。我已经使用和不使用选项测试了您的程序。没有选项,SIGQUIT被阻止;有了它,当我向它发送SIGQUIT信号时,信号没有被阻止,睡眠过程终止。
我能找到的最接近的解释是OpenJDK 6 java(1)手册页:
Sun的JVM捕获信号以实现异常JVM终止的关闭挂钩。 JVM使用SIGHUP,SIGINT和SIGTERM来启动关闭挂钩的运行。
JVM使用类似的机制来实现转储线程堆栈的1.2之前的功能,以便进行调试。 Sun的JVM使用SIGQUIT来执行线程转储。
嵌入JVM的应用程序经常需要捕获SIGINT或SIGTERM等信号,这会导致干扰JVM自己的信号处理程序。 -Xrs命令行选项可用于解决此问题。 在Sun的JVM上使用-Xrs时,JVM不会更改SIGINT,SIGTERM,SIGHUP和SIGQUIT的信号掩码,也不会安装这些信号的信号处理程序。 < / p>