【发布时间】:2013-12-30 10:39:36
【问题描述】:
我们有一个 Java 服务,它加载到 Linux 上的本机守护进程中。此守护进程阻止大多数信号并安装其自己的信号处理程序,因为此进程是一个通用的关键任务应用程序。这也是一个多线程应用程序,它大量利用 pthreads,HotSpot JVM 加载在其中一个线程中。
在 64 位 Linux(SLES,RH)上升级到 Java 7 JVM 后,我们注意到当套接字关闭时,没有收到 ServerSocket 等待连接的信号。根据JavaDoc,当前在accept() 中阻塞的任何线程都将抛出SocketException,这样我们在服务关闭时关闭侦听套接字。我们怀疑我们在本机过程中处理信号的方式,因为我们多年前有过类似的经历,结果变成了真的。
在我们的本机进程中,我们阻止信号如下(伪代码)。我们确实使用sigaction() 安装了我们自己的处理程序,下面没有显示。
sigset_t set;
sigfillset(&set);
sigdelset(&set, SIGTRAP);
sigdelset(&set, SIGSEGV);
/* Remove following signals as it appears to be used by JVM */
for (int s = SIGRTMIN; s <= SIGRTMAX-4; s++) {
sigdelset(&set, s);
}
if ((err = pthread_sigmask(SIG_BLOCK, &set, 0)) != 0) {
err_warn(“Unable to block signals: %d”, err);
}
/* pthread_create() for LoadJVM calls and continue.
Threads are detached and hence no join() */
/* Read current mask */
pthread_sigmask(SIG_BLOCK, 0, &set);
/* Wait on these signals */
while (bshutdown == false) {
if ((sig = sigwaitinfo(&set, &info)) == -1) {
/* something unexpected happened */
}
switch (sig) {
/* Do something */
}
}
我们在新的 JVM 中发现,如果我们从集合中删除 SIGRTMAX-2 和 SIGRTMAX-3,Java ServerSockets 在关闭时不会收到通知。目前,我们添加这两个信号并在加载 JVM 的线程中调用 pthread_sigmask(SIG_UNBLOCK, &set, 0) 来解决问题。
我的问题是:
- 有谁知道 JVM 是否使用这些信号。 JavaDoc on handling signals 没有列出它们。
- 在 Linux 上(在 x86_64 内核 2.6.32 上测试,
3.11.6),读取当前信号掩码(
pthread_sigmask(SIG_UNBLOCK, 0, &set))不会返回当前掩码。set只是 0。有 有人见过这种行为吗?它在 OSX 和 Solaris 上运行良好。
【问题讨论】:
-
您可以使用
strace找出... -
您也可以尝试从 OpenJDK 源中获取相关信号名称,或者可能是 POSIX 信号函数名称。
标签: java linux multithreading signals