我有一个带有专门的Process
类型的程序,它可以处理在Linux上本机执行的进程。
它根本不使用Java的Process类,因为它需要对该过程进行一些特殊处理。因此,它还为SIGCHLD
安装了自己的信号处理程序,以便它知道进程何时退出。
但是,我刚刚在我的代码中添加了一个Runtime.exec()
调用,这显然为SIGCHLD
安装了自己的信号处理程序,这意味着我再也没有得到SIGCHLD
,这很糟糕。我已按照oracle的信号链指示进行操作,但同样的问题发生了,我从未得到SIGCHLD
。
所以,基本问题是:是否可以在Java中链接SIGCHLD
?
答案 0 :(得分:5)
libjsig
无效,因为SIGCHLD
处理程序由libjava
安装,而不是由JVM本身安装。
sigaction(SIGCHLD, ...)
的 SIG_DFL
在java.lang.UNIXProcess的静态初始化程序中只被Java类库调用一次。
现在您有以下选项可以解决此问题。
最简单的一个。只需在java.lang.UNIXProcess
初始化后安装信号处理程序。
创建您自己的LD_PRELOAD
挂钩,拦截sigaction
并在使用SIGCHLD
和SIG_DFL
参数调用时忽略它:
E.g。
#define _GNU_SOURCE
#include <signal.h>
#include <dlfcn.h>
#include <stddef.h>
int sigaction(int signum, const struct sigaction* act, struct sigaction* oldact) {
static int (*real_sa)(int, const struct sigaction*, struct sigaction*) = NULL;
if (signum == SIGCHLD && act->sa_handler == SIG_DFL) {
return 0;
}
if (real_sa == NULL) {
real_sa = dlsym(RTLD_NEXT, "sigaction");
}
return real_sa(signum, act, oldact);
}
答案 1 :(得分:-2)
如何使用套接字与您的子进程进行通信而不是SIGCHLD? 我假设您自己创建子进程代码。