Есть демон, который создаёт воркеры через fork. Нужно сделать возможность рестарта воркеров (старые убиваются, новые создаются). Посылаю SIGTERM воркерам, они нормально завершаются. На SIGCHLD вызываю wait. Зомби пропадают. После этого перед тем как запустить новые воркеры снова вызываю wait. Выглядит всё это как-то так: PHP: <?php // ... function _SIGCHLD() { pcntl_wait($status); } // ... worker_stop_graceful_all(); pcntl_wait($status); // если убрать этот wait, то 2 из 3 зомби останутся worker_start_all(); Ну и собственно проблема в том, что после всех этих манипуляций мастер процесс перестаёт реагировать на сигналы: Код (Text): # php daemon.php # ps ax | grep php 7708 ? S 0:00 php daemon.php 7709 ? Ss 0:00 php daemon.php 7710 ? Ss 0:00 php daemon.php 7711 ? Ss 0:00 php daemon.php 7715 pts/1 R+ 0:00 grep php # kill -s HUP `cat wtf.pid` # ps ax | grep php 7708 ? S 0:00 php daemon.php 7717 ? Ss 0:00 php daemon.php 7718 ? Ss 0:00 php daemon.php 7719 ? Ss 0:00 php daemon.php 7721 pts/1 R+ 0:00 grep php # kill -s TERM `cat wtf.pid` # ps ax | grep php 7708 ? S 0:00 php daemon.php 7717 ? Ss 0:00 php daemon.php 7718 ? Ss 0:00 php daemon.php 7719 ? Ss 0:00 php daemon.php 7724 pts/1 R+ 0:00 grep php Может кто-нибудь решал подобную задачу? upd1: был не прав, мастер реагирует на сигналы, а вот воркеры на posix_kill($pid, SIGTERM) не отзываются.
Локализовал проблему. Вынес из обработчика SIGHUP всю обработку, ставлю в нём только флаг. Это флаг проверяет мастер и выполняет всю грязную работу. Так же изменил обработчик SIGCHLD PHP: while (pcntl_waitpid(-1, $status, WNOHANG) > 0) {/* */} и убрал wait между остановом и запуском воркеров.