SIGCHLD n’est pas pris dans epoll_wait?

Je voulais comprendre le comportement des signaux sur une fourche. J’ai écrit un petit programme pour attraper SIGCHLD avec epoll_wait mais quand je fais un “kill -9” sur l’enfant forké, je ne reçois aucun signal et l’enfant est dans un état obsolète (j’ai un gestionnaire qui attend ()) .

Voici le code.

//.... sigemptyset(&mask); sigaddset(&mask, SIGCHLD); pthread_sigmask(SIG_BLOCK, &mask, NULL); signal_fd = signalfd(-1, &mask, 0); memset(&tev, 0, sizeof(tev)); tev.events = EPOLLIN | EPOLLONESHOT; tev.data.fd = signal_fd; epoll_ctl(efd_, EPOLL_CTL_MOD, signal_fd, &tev); while (1) { child_pid_ = fork(); if (child_pid_ == 0) { close(signal_fd); close(efd_); make_grand_child(); //just sleeps in while(1) and never returns. } else { memset(&event, 0, sizeof(event)); while (1) { epoll_wait(efd_, &event, 1, -1); deliver_events = (event.events & EPOLLERR|EPOLLHUP|EPOLLIN|EPOLLONESHOT); if (deliver_events) { parent_sig_handler(SIGCHLD); break; } } } } 

METTRE À JOUR:

Utilisé un EPOLL_CTL_MOD sans d’abord effectuer une addition (EPOLL_CTL_ADD). Après avoir changé cela, cela a fonctionné à merveille.

La disposition par défaut de SIGCHLD doit être ignorée. Le blocage du signal ne changera pas la disposition, il donnera simplement à signalfd la possibilité de le traiter de manière synchrone.

Ajoutez un gestionnaire de signal pour SIGCHLD avec signal ou sigaction . Il n’a rien à faire car il ne sera pas exécuté. Comme SIGCHLD est bloqué, signalfd le consumra et le traitera avant le gestionnaire.