За последние 24 часа нас посетил 9731 программист и 470 роботов. Сейчас ищут 212 программистов ...

pcntl_fork + pcntl_wait

Тема в разделе "Прочие вопросы по PHP", создана пользователем Sergey89, 1 мар 2009.

  1. Sergey89

    Sergey89 Активный пользователь

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    Есть демон, который создаёт воркеры через fork. Нужно сделать возможность рестарта воркеров (старые убиваются, новые создаются).

    Посылаю SIGTERM воркерам, они нормально завершаются. На SIGCHLD вызываю wait. Зомби пропадают. После этого перед тем как запустить новые воркеры снова вызываю wait. Выглядит всё это как-то так:
    PHP:
    1. <?php
    2. // ...
    3. function _SIGCHLD() {
    4.     pcntl_wait($status);
    5. }
    6. // ...
    7. worker_stop_graceful_all();
    8. pcntl_wait($status); // если убрать этот wait, то 2 из 3 зомби останутся
    9. worker_start_all();
    Ну и собственно проблема в том, что после всех этих манипуляций мастер процесс перестаёт реагировать на сигналы:

    Код (Text):
    1. # php daemon.php
    2. # ps ax | grep php
    3.  7708 ?        S      0:00 php daemon.php
    4.  7709 ?        Ss     0:00 php daemon.php
    5.  7710 ?        Ss     0:00 php daemon.php
    6.  7711 ?        Ss     0:00 php daemon.php
    7.  7715 pts/1    R+     0:00 grep php
    8. # kill -s HUP `cat wtf.pid`
    9. # ps ax | grep php
    10.  7708 ?        S      0:00 php daemon.php
    11.  7717 ?        Ss     0:00 php daemon.php
    12.  7718 ?        Ss     0:00 php daemon.php
    13.  7719 ?        Ss     0:00 php daemon.php
    14.  7721 pts/1    R+     0:00 grep php
    15. # kill -s TERM `cat wtf.pid`
    16. # ps ax | grep php
    17.  7708 ?        S      0:00 php daemon.php
    18.  7717 ?        Ss     0:00 php daemon.php
    19.  7718 ?        Ss     0:00 php daemon.php
    20.  7719 ?        Ss     0:00 php daemon.php
    21.  7724 pts/1    R+     0:00 grep php
    Может кто-нибудь решал подобную задачу?

    upd1: был не прав, мастер реагирует на сигналы, а вот воркеры на posix_kill($pid, SIGTERM) не отзываются.
     
  2. Sergey89

    Sergey89 Активный пользователь

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    Локализовал проблему. Вынес из обработчика SIGHUP всю обработку, ставлю в нём только флаг. Это флаг проверяет мастер и выполняет всю грязную работу.

    Так же изменил обработчик SIGCHLD
    PHP:
    1. while (pcntl_waitpid(-1, $status, WNOHANG) > 0) {/* */}
    и убрал wait между остановом и запуском воркеров.