Подтвердить что ты не робот

Соединение Java-сигналов

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

  • Создайте свой собственный крюк 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);
}

Ответ 2

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