Родительский ребенок не улавливает сигнал после разветвления

У меня странная проблема в PHP с Symfony 1.4.

У меня есть задача, которая запускает несколько воркеров, и иногда мне нужно остановить всех воркеров (например, после развертывания).

Я запускаю задачу с помощью start-stop-daemon, и я хочу остановить ее, отправив ей сигнал SIGINT.

Итак, вот мой код:

protected function execute($arguments = array(), $options = array())
{
    $pid_arr = array();
    $thread = $this->forkChildren($arguments, $options, $options['nb_children']);

    if ($this->iAmParent())
    {
        declare(ticks = 1);
        pcntl_signal(SIGINT, array($this, 'signalHandler'));
        // Retrieve list of children PIDs
        $pid_arr = $this->getChildrenPids();
        // While there are still children processes
        while(count($pid_arr) > 0)
        {
            $myId = pcntl_waitpid(-1, $status);
            foreach($pid_arr as $key => $pid)
            {
                // If the stopped process is indeed a children of the parent process
                if ($myId == $pid)
                {
                    $this->removeChildrenPid($key);
                    // Recreate a child
                    $this->createNewChildren($arguments, $options, 1, $pid_arr);
                }
            }
            usleep(1000000);
            $pid_arr = $this->getChildrenPids();
        }
    }
    else
        $thread->run();
}

public function signalHandler($signal)
{
    echo "HANDLED SIGNAL $signal\n";
    foreach ($this->getChildrenPids() as $childrenPid)
    {
        echo "KILLING $childrenPid\n";
        posix_kill($childrenPid, $signal);
    }
    exit();
}

То, что я делаю, довольно просто: я разветвляю, создаю N дочерних процессов и добавляю в родительский процесс pcntl_signal для перехвата сигнала SIGINT. Функция signalHanlder извлекает список дочерних pid и отправляет им тот же сигнал, который она только что получила (т. е. SIGINT).

Проблема в том, что функция signalHandler никогда не вызывается, когда я отправляю сигнал INT (через kill) родительскому процессу. И я не понимаю, почему!

Странно то, что когда я запускаю свою задачу в cli и использую Ctrl-C, вызывается функция signalHandler, и все дочерние элементы останавливаются.

Итак, вы понимаете, почему это происходит? Я делаю что-то неправильно?


person Talal MAZROUI    schedule 21.01.2014    source источник


Ответы (1)


Хорошо, забудьте об этом, я обнаружил проблему сразу после того, как задал вопрос:

я только что заменил

$myId = pcntl_waitpid(-1, $status);

by

$myId = pcntl_waitpid(-1, $status, WNOHANG);

потому что естественно процесс завис в ожидании смерти одного из детей.

person Talal MAZROUI    schedule 21.01.2014