3

保護者/労働者の取り決めが進行中です。親はワーカー PID を配列に保持し、次のループでそれらがまだ生きていることを常にチェックします。

// $workers is an array of PIDs
foreach ($workers as $workerID => $pid) {
    // Check if this worker still exists as a process
    pcntl_waitpid($pid, $status, WNOHANG|WUNTRACED);

    // If the worker exited normally, stop tracking it
    if (pcntl_wifexited($status)) {
        $logger->info("Worker $workerID exited normally");
        array_splice($workers, $workerID, 1); 
    }

    // If it has a session ID, then it's still living
    if (posix_getsid($pid))⋅
        $living[] = $pid;
}

// $dead is the difference between workers we've started
// and those that are still running
$dead = array_diff($workers, $living);

問題は、pcntl_waitpid()常に$status0 に設定されていることです。そのため、このループが最初に実行されると、親は、まだ実行されているにもかかわらず、すべての子が正常に終了したと見なします。私はpcntl_waitpid()間違って使用していますか、それともそうでないことを期待していますか?

4

2 に答える 2

3

シンプルです。子は終了または停止していません。フラグを追加したWNOHANGので、常にすぐに戻ります (イベントを待機しないように関数に指示します)。すべきことは、 の戻り値をチェックしてpcntl_waitpid、何か値が返されたかどうかを確認することです (ステータスが変化した場合にのみループの内容を実行したいと仮定します)。

foreach ($workers as $workerID => $pid) {
    // Check if this worker still exists as a process
    if (pcntl_waitpid($pid, $status, WNOHANG|WUNTRACED)) {
        // If the worker exited normally, stop tracking it
        if (pcntl_wifexited($status)) {
            $logger->info("Worker $workerID exited normally");
            array_splice($workers, $workerID, 1); 
        }
        // If it has a session ID, then it's still living
        if (posix_getsid($pid))⋅
            $living[] = $pid;
    }
}    
于 2011-01-03T16:27:01.837 に答える
2

あなたは確かに「pcntl_waitpid()間違った使い方」をしています(引用符に注意してください)

を使用しているため、 が子の PID を返す場合WNOHANGのみ、 の内容を評価できます。pcntl_waitpid()$status

の戻り値を参照してくださいpcntl_waitpid()

于 2011-01-03T16:27:05.997 に答える