pcntl_signal не запускается дочерним процессом

#php #pcntl

#php #pcntl

Вопрос:

Я хочу добиться этого:

если демон получает SIGHUP, запустите процесс снова (как дочерний) и убейте родительский.

Когда я запускаю его, первый раз работает:

 > php test.php
> kill -HUP pid
> ps -ef |grep test.php
> result:... newPID test.php
  

Проблема в том, что если сейчас я завершаю дочерний процесс, функция не запускается

 > kill -HUP newPID
> ps -ef |grep test.php
> result: ... newPID(the same) test.php
  

Код:

 test.php:
<?php
   declare(ticks = 1);

   $mypid = posix_getpid();

   function sig_handler()
   {

   Global $mypid;
   echo "Received sighup, we need to reload ourselves now n";
   echo "mypid:$mypid n";
   system("(php test.php)>/dev/null amp;");

   posix_kill($mypid,9);

   }

   pcntl_signal(SIGHUP,  "sig_handler");

   sleep(500);

   ?>
  

Этот код работает на PHP 5.2.9, но не на PHP 5.3.5. Есть ли какой-нибудь способ заставить его работать и на этой версии?

Спасибо!

Ронни

Ответ №1:

Обработчики сигналов в PHP не являются повторными. Таким образом, любой процесс, который вы разветвляете / порождаете изнутри обработчика сигналов, сам по себе не может реагировать на сигналы. Я хотел бы увидеть подробности, работал ли этот точный код в PHP 5.2.9, потому что, насколько мне известно, это поведение было последовательным.

Итак, что вы можете сделать?

Во многих случаях лучшим вариантом является установка флага $ signal_recd внутри обработчика сигналов, который вы периодически опрашиваете в своем приложении.

Я автор довольно популярной библиотеки PHP Daemon,https://github.com/shaneharter/PHP-Daemon

На вашем месте я бы просто создал ваше приложение на этом и позволил ему беспокоиться об автоматическом перезапуске и т.д. Но, если ничего другого, вы, вероятно, можете посмотреть на это Core_Daemon::auto_restart() и код обработки сигналов.

Ответ №2:

Я подозреваю, что это ошибка в PHP. Я все еще пытаюсь подтвердить с абсолютной уверенностью, но в нынешнем виде у нас та же проблема.

Если вы запустите дочерний процесс и отправите сигнал, дочерний процесс получит и обработает сигнал. Если впоследствии вы повторно запустите другой дочерний процесс из родительского скрипта и выполните другой сигнал, второй сигнал дочерним процессом не будет получен. Я настраивал, вертел и трудился, чтобы найти способ обойти эту проблему в PHP 5.3.10, но безрезультатно.

Комментарии:

1. смотрите ответ, который я только что оставил для OP. Обработчики сигналов в PHP не являются повторными. Это сделано специально, а не ошибка.