0

symfony 1.4 で PHP に奇妙な問題が発生しています

複数のワーカーを起動するタスクがあり、場合によってはすべてのワーカーを停止する必要があります (たとえば、デプロイ後)。

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) を送信します。

問題は、INT シグナルを (kill 経由で) 親プロセスに送信したときに、signalHandler 関数が呼び出されないことです。そして、私はその理由を理解していません!

奇妙なことに、cli でタスクを起動して Ctrl-C を使用すると、signalHandler 関数が呼び出され、すべての子が停止します。

では、なぜこれが起こっているのか理解できますか?私は何か間違ったことをしていますか?

4

1 に答える 1

0

OK、忘れてください。質問をした直後に問題が見つかりました。

交換したばかり

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

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

もちろん、プロセスは子供の 1 人が死ぬのを待ってハングしていました。

于 2014-01-21T10:29:16.000 に答える