java linux signal-handling sigchld runtime-environment

Encadenamiento de señal de Java



linux signal-handling (2)

¿Qué le parece usar sockets para comunicarse con el proceso de su hijo en lugar de SIGCHLD? Supongo que usted crea el código de proceso hijo usted mismo.

Tengo un programa con una clase de tipo de Process especializada que se encarga de ejecutar los procesos de forma nativa en Linux.

No utiliza la clase de Process de Java en absoluto, porque necesita hacer un manejo especial del proceso. Debido a esto, también instala su propio controlador de señal para SIGCHLD , de modo que sepa cuándo sale un proceso.

Sin embargo, acabo de agregar una llamada Runtime.exec() en mi código, que aparentemente instala su propio controlador de señal para SIGCHLD , lo que significa que nunca más recibo un SIGCHLD , lo cual es malo. He seguido las instrucciones para encadenar señales de oracle , pero ocurre el mismo problema: nunca obtengo un SIGCHLD .

Entonces, la pregunta básica es esta: ¿es posible encadenar SIGCHLD en Java?


libjsig no ayuda, porque el controlador SIGCHLD está instalado por libjava , no por JVM.

Java Class Library llama a sigaction(SIGCHLD, ...) con sa_handler = SIG_DFL en el inicializador estático de java.lang.UNIXProcess.

Ahora tienes las siguientes opciones para solucionar esto.

  1. La más fácil. Simplemente instale su manejador de señal después de la inicialización de java.lang.UNIXProcess .

  2. Cree su propio gancho LD_PRELOAD que interceptará sigaction e sigaction cuando se le llame con los argumentos SIGCHLD y SIG_DFL :

P.ej

#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); }