如果从Java启动,子进程将忽略SIGQUIT

时间:2017-03-23 15:41:01

标签: java linux signals

举个简单的例子:

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信号,它会忽略它。其他信号(SIGINTSIGTERM等)都可以正常工作,但SIGQUIT会被忽略。如果我只是在不使用Java的情况下从shell运行sleep 1000,那么SIGQUIT将得到正确处理。

为什么行为不同?

1 个答案:

答案 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>