Java 信号链

我有一个程序,其中包含一个专门的类型类,该类处理在Linux上本机执行进程。Process

它根本不使用Java的Process类,因为它需要对进程进行一些特殊的处理。因此,它还会为 安装自己的信号处理程序,以便知道进程何时退出。SIGCHLD

但是,我刚刚在我的代码中添加了一个调用,它显然安装了自己的信号处理程序,这意味着我永远不会再得到一个,这很糟糕。我已经遵循了oracle的信号链指令,但是同样的问题发生了,我从来没有得到过.Runtime.exec()SIGCHLDSIGCHLDSIGCHLD

所以,基本问题是:在Java中可以链接吗?SIGCHLD


答案 1

libjsig没有帮助,因为处理程序是由 安装的,而不是由 JVM 本身安装的。SIGCHLDlibjava

sigaction(SIGCHLD, ...)with sa_handler = 仅由 java.lang.UNIXProcess 的静态初始值设定项中的 Java 类库调用一次。SIG_DFL

现在,您可以通过以下选项来解决此问题。

  1. 最简单的一个。只需在 初始化 后安装信号处理程序。java.lang.UNIXProcess

  2. 创建你自己的钩子,它将在调用 with 和 参数时拦截并忽略它:LD_PRELOADsigactionSIGCHLDSIG_DFL

例如:

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

答案 2

使用套接字代替SIGCHLD与您的孩子进行通信怎么样?我假设您自己创建子流程代码。


推荐