please note, if you using configure option --enable-sigchild(Enable PHP's own SIGCHLD handler) when complie php(under linux 2.6.18-53.1.13.el5.centos.plus and php 5.2.5 as I know), pcntl_waitpid and pcntl_wait in php script would never return the child pid, because the build in handle get it first.
pcntl_waitpid
(PHP 4 >= 4.0.7, PHP 5)
pcntl_waitpid — 待つかフォークした子プロセスのステータスを返す
説明
引数 pid で指定した子プロセスが終了する・ 現在のプロセスを終了させるシグナルが送信される・シグナル処理関数を コールするシグナルが送信される のいずれかが発生するまで、現在のプロセスの実行を中断します。
pid でリクエストされた子プロセスが、 コール時に 既に終了している場合("ゾンビ"プロセスと呼ばれます)、この関数は 直ちに処理を返します。子プロセスにより使用される全てのシステム リソースは、解放されます。waitpid のシステムでの動作に関する詳細は、 システムの waitpid(2) についての man ページを参照ください。
パラメータ
- pid
-
pid の値は、次のどれかとなります。
pid のとりうる値 < -1 プロセスグループ ID が pid の絶対値に等しい 子プロセスを待ちます。 -1 全ての子プロセスを待ちます。これは、wait 関数の動作と同じです。 0 プロセスグループ ID がコール側のプロセスと等しい子プロセスを 待ちます。 > 0 プロセス ID が pid の値に等しい 子プロセスを待ちます。 注意: -1 を pid に指定した際の動きは、 pcntl_wait() の機能と (options を除いて) 同じです。
- status
-
pcntl_waitpid() は、パラメータ status の中にステータス情報を保存します。 このステータスは、次の関数を用いて評価可能です。 pcntl_wifexited()、 pcntl_wifstopped()、 pcntl_wifsignaled()、 pcntl_wexitstatus()、 pcntl_wtermsig() および pcntl_wstopsig() 。
- options
-
options の値は、次の 2 つのグローバル定数の ゼロまたはそれ以上の論理和です。
options のとりうる値 WNOHANG 子プロセスが終了していない場合に直ちに処理を返します。 WUNTRACED 停止した子プロセスの場合に処理を返します。そして、ステータス は報告されません。
返り値
pcntl_waitpid() は、終了した子プロセスの プロセス ID を返します。エラーの場合は -1、WNOHANG が使用され、 子プロセスが利用できない場合に 0 を返します。
pcntl_waitpid
09-Apr-2008 09:09
10-May-2006 03:40
---
while ($i < intval($argv[1]))
{
$pid = pcntl_fork();
if ($pid == -1)
{
die('could not fork');
}
else
{
if ($pid) // parent
{
$pid_arr[$i] = $pid;
}
else // child
{
performSomeFunction($i+1);
}
}
$i++;
}
---
careful, this will create a lot more children than you probably expect. You must return or exit after performSomeFunction($i+1); ie,
else // child
{
performSomeFunction($i+1);
exit(0);
}
06-Mar-2006 10:48
Here's a decent example of the pcntl_waitpid() call:
$i = 0;
$starttime = microtime(TRUE);
$pid_arr = array();
while ($i < intval($argv[1]))
{
$pid = pcntl_fork();
if ($pid == -1)
{
die('could not fork');
}
else
{
if ($pid) // parent
{
$pid_arr[$i] = $pid;
}
else // child
{
performSomeFunction($i+1);
}
}
$i++;
}
foreach ($pid_arr as $pid)
{
// we are the parent
pcntl_waitpid($pid, $status);
}
$elapsed = microtime(TRUE) - $starttime;
print "\n==> total elapsed: " . sprintf("%f secs.\n", $elapsed);
