Цепочка сигналов Java

У меня есть программа со специализированным Processкласс -типа, который обрабатывает процессы, выполняемые непосредственно в Linux.

Он вообще не использует Java-класс Process, потому что ему требуется особая обработка процесса. Из-за этого он также устанавливает свой собственный обработчик сигнала для SIGCHLD, чтобы он знал, когда завершается процесс.

Тем не менее, я просто добавил Runtime.exec() вызов в моем коде, который, очевидно, устанавливает свой собственный обработчик сигнала для SIGCHLDЭто означает, что я никогда не получу SIGCHLD опять же, что плохо. Я следовал инструкциям цепочки сигналов от оракула, но возникает та же проблема, я никогда не получаю SIGCHLD,

Итак, основной вопрос заключается в следующем: возможно ли связать SIGCHLD на яве?

2 ответа

Решение

libjsig не помогает, потому что SIGCHLD обработчик устанавливается libjavaне самой JVM.

sigaction(SIGCHLD, ...) с sa_handler = SIG_DFL вызывается только один раз библиотекой классов Java в статическом инициализаторе java.lang.UNIXProcess.

Теперь у вас есть следующие варианты, чтобы обойти это.

  1. Самый простой. Просто установите ваш обработчик сигнала после инициализации java.lang.UNIXProcess,

  2. Создайте свой собственный LD_PRELOAD крючок, который будет перехватывать sigaction и игнорировать его при вызове с SIGCHLD а также SIG_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);
}

Как насчет использования сокетов для связи с вашим дочерним процессом вместо SIGCHLD? Я предполагаю, что вы сами создаете код дочернего процесса.

Другие вопросы по тегам