Обработка нескольких SIGCHLD - PullRequest
18 голосов
/ 06 декабря 2011

В системе под управлением Linux 2.6.35+ моя программа создает множество дочерних процессов и контролирует их.Если дочерний процесс умирает, я делаю некоторую очистку и порождаю процесс снова.Я использую signalfd(), чтобы получить сигнал SIGCHLD в моем процессе.signalfd используется асинхронно с использованием libevent.

При использовании обработчиков сигналов для сигналов не в реальном времени, когда обработчик сигналов работает для определенного сигнала, дальнейшее появление того же сигнала должно быть заблокировано, чтобы избежатьпопасть в рекурсивные обработчики.Если в это время поступает несколько сигналов, то ядро ​​вызывает обработчик только один раз (когда сигнал разблокирован).

То же самое происходит и при использовании signalfd()?Поскольку обработка на основе signalfd не имеет типичных проблем, связанных с асинхронным выполнением обычных обработчиков сигналов, я думал, ядро ​​может поставить в очередь все дальнейшие вхождения SIGCHLD?

Может кто-нибудь прояснить поведение Linux в этом случае ...

Ответы [ 2 ]

21 голосов
/ 06 декабря 2011

В Linux несколько дочерних элементов, заканчивающихся до того, как вы прочитаете SIGCHLD с signalfd(), будут сжаты в один SIGCHLD.Это означает, что когда вы читаете сигнал SIGCHLD, вы должны очистить после всех детей, которые прекратили:

// Do this after you've read() a SIGCHLD from the signalfd file descriptor:
while (1) {
    int status;
    pid_t pid = waitpid(-1, &status, WNOHANG);
    if (pid <= 0) {
        break;
    }
    // something happened with child 'pid', do something about it...
    // Details are in 'status', see waitpid() manpage
}

Я должен отметить, что на самом деле я видел этот сигналсжатие, когда два дочерних обработчика прекращаются одновременно.Если бы я сделал только один waitpid(), один из детей, который закончил, не был обработан;и вышеупомянутый цикл исправил это.

Соответствующая документация:

  • http://man7.org/linux/man-pages/man7/signal.7.html "В отличие от этого, если несколько экземпляров стандартного сигнала доставляются во время этого сигналав настоящее время заблокирован, тогда только один экземпляр ставится в очередь "
  • http://man7.org/linux/man-pages/man3/sigwait.3p.html " Если до вызова sigwait () существует несколько ожидающих экземпляров одного номера сигнала,определяется реализацией, есть ли после успешного возврата какие-либо оставшиеся ожидающие сигналы для этого номера сигнала. "
0 голосов
/ 23 октября 2013

На самом деле беспроблемным способом будет функционально waitfd, который позволит вам добавить определенный pid в poll () / epoll (). К сожалению, он не был принят в Linux много лет назад, когда он был предложен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...