<?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);
}