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

2024-04-30

举这个简单的例子:

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);
    }
}

我在 Linux 上使用 openjdk6 运行它。如果我尝试发送SIGQUIT向“睡眠”进程发出信号,它会忽略它。其他信号(SIGINT, SIGTERM等)一切正常,但是SIGQUIT被忽略。如果我只是跑sleep 1000从 shell 中而不使用 Java,然后SIGQUIT处理得当。

为什么行为不同?


通过java的-Xrs选项。我已经在有和没有选项的情况下测试了你的程序。如果没有该选项,SIGQUIT 会被阻止;有了它,当我向它发送 SIGQUIT 信号时,信号不会被阻塞,并且睡眠进程会终止。

我能找到的关于发生的事情的最接近的解释是OpenJDK 6 java(1) https://linux.die.net/man/1/java-java-1.6.0-openjdk手册页:

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 的信号掩码,并且不会安装这些信号的信号处理程序。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如果从 Java 启动,子进程将忽略 SIGQUIT 的相关文章

随机推荐