2011-01-03 1 views
2

私は親/就労協定を結んでいます。親は常に彼らはまだ、次のループで生きていることを確認し、配列内の労働者の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()は常に0に$statusを設定しているので、非常に最初の時間は、このループが実行されるということです親は、まだ実行中であっても、すべての子どもが正常に終了したと考えます。 pcntl_waitpid()を間違って使用していますか、それともそうでないことを期待していますか?

答えて

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; 
    } 
}  
2

あなたは確かですあなたが子供のPID WNOHANGのみpcntl_waitpid()場合リターンを使用しているので

(引用符に注意してください)「pcntl_waitpid()間違っているが使用して」、あなたは$statusに何があるか評価することができます。

pcntl_waitpid()の場合はreturn valuesを参照してください。