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

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

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

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

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


person rm5248    schedule 20.09.2013    source источник
comment
Какой из двух описанных способов вы пробовали?   -  person allprog    schedule 22.09.2013
comment
Использование LD_PRELOAD; Я не пробовал создавать приложение, которое встраивает JVM.   -  person rm5248    schedule 22.09.2013
comment
Я также награжу BOUNTY в размере 100 за успешный ответ. (Сейчас я не могу, так как за один вопрос может быть только одна награда)   -  person Jatin    schedule 12.08.2014
comment
Вы пробовали вариант -Xrs для java?   -  person Jojje    schedule 12.08.2014


Ответы (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:

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);
}
person apangin    schedule 12.08.2014

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

person HWJ    schedule 11.08.2014