Java信号链

时间:2013-09-20 16:34:31

标签: java linux signal-handling sigchld runtime-environment

我有一个带有专门的Process类型的程序,它可以处理在Linux上本机执行的进程。

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

但是,我刚刚在我的代码中添加了一个Runtime.exec()调用,这显然为SIGCHLD安装了自己的信号处理程序,这意味着我再也没有得到SIGCHLD,这很糟糕。我已按照oracle的信号链指示进行操作,但同样的问题发生了,我从未得到SIGCHLD

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

2 个答案:

答案 0 :(得分:5)

libjsig无效,因为SIGCHLD处理程序由libjava安装,而不是由JVM本身安装。

带有sa_handler = sigaction(SIGCHLD, ...)

SIG_DFL在java.lang.UNIXProcess的静态初始化程序中只被Java类库调用一次。

现在您有以下选项可以解决此问题。

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

  2. 创建您自己的LD_PRELOAD挂钩,拦截sigaction并在使用SIGCHLDSIG_DFL参数调用时忽略它:

  3. 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? 我假设您自己创建子进程代码。