Цепочка сигналов 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.
Теперь у вас есть следующие варианты, чтобы обойти это.
Самый простой. Просто установите ваш обработчик сигнала после инициализации
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);
}
Как насчет использования сокетов для связи с вашим дочерним процессом вместо SIGCHLD? Я предполагаю, что вы сами создаете код дочернего процесса.