(PHP 4 >= 4.1.0, PHP 5, PHP 7, PHP 8)
pcntl_waitpid — 待つかフォークした子プロセスのステータスを返す
$process_id,&$status,$flags = 0,&$resource_usage = []
引数 process_id で指定した子プロセスが終了する・
現在のプロセスを終了させるシグナルが送信される・シグナル処理関数を
コールするシグナルが送信される
のいずれかが発生するまで、現在のプロセスの実行を中断します。
process_id でリクエストされた子プロセスが、
コール時に既に終了している場合("ゾンビ"プロセスと呼ばれます)、
この関数は直ちに処理を返します。
子プロセスにより使用される全てのシステム
リソースは、解放されます。waitpid のシステムでの動作に関する詳細は、
システムの waitpid(2) についての man ページを参照ください。
process_id
process_id の値は、次のどれかとなります。
< -1 |
プロセスグループ ID が process_id の絶対値に等しい
子プロセスを待ちます。
|
-1 |
いずれかの子プロセスを待ちます。これは、 pcntl_wait() 関数の動作と同じです。 |
0 |
プロセスグループ ID がコール側のプロセスと等しい子プロセスを 待ちます。 |
> 0 |
プロセス ID が process_id の値に等しい
子プロセスを待ちます。
|
注意:
-1をprocess_idに指定した際の動きは、 pcntl_wait() の機能と (flagsを除いて) 同じです。
status
pcntl_waitpid() は、パラメータ
status の中にステータス情報を保存します。
このステータスは、次の関数を用いて評価可能です。
pcntl_wifexited()、
pcntl_wifstopped()、
pcntl_wifsignaled()、
pcntl_wexitstatus()、
pcntl_wtermsig() および
pcntl_wstopsig() 。
flags
flags の値は、次の 2 つのグローバル定数の
ゼロまたはそれ以上の論理和です。
WNOHANG |
子プロセスが終了していない場合に直ちに処理を返します。 |
WUNTRACED |
停止していて、かつステータスがまだ報告されていない 子プロセスの場合にも処理を返します。 |
resource_usage
resource_usage パラメータには、子プロセスの
リソース使用状況の統計情報を含む連想配列が設定されます。
内容については getrusage() を参照ください。
これは、システム上で wait4(2)
システムコールが使用可能な場合にのみサポートされます。
使用できない場合、このパラメータは変更されません。
回収された子プロセスがない場合、つまりこの関数が 0
または -1 を返した場合は、
このパラメータには空の配列が設定されます。
pcntl_waitpid() は、終了した子プロセスの
プロセス ID を返します。エラーの場合は -1、WNOHANG が使用され、
子プロセスが利用できない場合に 0 を返します。
例1 pcntl_waitpid() の例
<?php
function checkChild(int $pid, bool $wait): void
{
$flags = ($wait ? 0 : WNOHANG);
$deadPid = pcntl_waitpid($pid, $status, $flags, $rusage);
if ($deadPid === -1) {
$errNo = pcntl_get_last_error();
$errMsg = pcntl_strerror($errNo);
print "PARENT pcntl_waitpid FAILED ({$errNo}): {$errMsg}\n";
} elseif ($deadPid === 0) {
print "PARENT pcntl_waitpid: No exited children.\n";
} elseif (pcntl_wifexited($status)) {
print "PARENT pcntl_waitpid: Child PID {$deadPid} exited with status: "
. pcntl_wexitstatus($status) . "\n";
var_dump($rusage);
} else {
print "PARENT pcntl_waitpid: Child PID {$deadPid} was terminated by signal: "
. pcntl_wtermsig($status) . "\n";
}
}
$parentPid = getmypid();
$forkedPid = pcntl_fork();
if ($forkedPid == -1) {
die('Could not fork');
} else if ($forkedPid) {
// 親プロセス
print "PARENT {$parentPid} has forked {$forkedPid}\n";
print "PARENT is checking for exited children\n";
checkChild($forkedPid, false);
// 子プロセスが「ゾンビプロセス」として残るのを防ぎます
print "PARENT is waiting for a child to exit\n";
checkChild($forkedPid, true);
print "PARENT is checking for exited children\n";
checkChild($forkedPid, false);
print "PARENT is exiting\n";
} else {
// 子プロセス
$pid = getmypid();
print "CHILD {$pid} is sleeping\n";
sleep(10);
print "CHILD is exiting\n";
exit(7);
}