pcntl_waitpid

(PHP 4 >= 4.1.0, PHP 5, PHP 7, PHP 8)

pcntl_waitpid等待或返回派生子进程的状态

描述

pcntl_waitpid(
    int $process_id,
    int &$status,
    int $flags = 0,
    array &$resource_usage = []
): int

挂起当前进程的执行,直到由 process_id 参数指定的子进程退出,或者直到传递一个信号,其操作是终止当前进程或调用信号处理函数。

如果在调用时,由 process_id 请求的子进程已经退出(所谓的“僵尸”进程),则函数立即返回。子进程使用的任何系统资源都将被释放。请参阅您系统的 waitpid(2) 手册页,了解 waitpid 在您系统上的具体工作方式。

参数

process_id

process_id 的值可以是以下值之一

process_id 的可能值
< -1 等待任何进程组 ID 等于 process_id 的绝对值的子进程。
-1 等待任何子进程;这与 wait 函数的行为相同。
0 等待任何进程组 ID 等于调用进程的进程组 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 的值是以下两个全局常量中的一个或多个的值进行 OR 运算后的结果

flags 的可能值
WNOHANG 如果没有任何子进程退出,则立即返回。
WUNTRACED 对于已停止的子进程,如果其状态尚未报告,则返回。

返回值

pcntl_waitpid() 返回退出的子进程的进程 ID,在发生错误时返回 -1,或者如果使用了 WNOHANG 并且没有任何子进程可用,则返回零

参见

添加说明

用户贡献说明 3 说明

saguto dot l7cc at gmail dot com
16 年前
请注意,如果您在编译 php 时使用配置选项 --enable-sigchild(启用 PHP 自身的 SIGCHLD 处理程序)(在我了解的 Linux 2.6.18-53.1.13.el5.centos.plus 和 php 5.2.5 环境下),php 脚本中的 pcntl_waitpid 和 pcntl_wait 永远不会返回子进程 pid,因为内置的处理程序会先获取它。
fx4084 at gmail dot com
9 年前
<?php
$childs
= array();

// 派生一些进程。
for($i = 0; $i < 10; $i++) {
$pid = pcntl_fork();
if(
$pid == -1)
die(
'Could not fork');

if (
$pid) {
echo
"parent \n";
$childs[] = $pid;
} else {
// 休眠 $i+1 (s)。子进程可以获取此参数($i)。
sleep($i+1);

// 子进程需要结束循环。
exit();
}
}

while(
count($childs) > 0) {
foreach(
$childs as $key => $pid) {
$res = pcntl_waitpid($pid, $status, WNOHANG);

// 如果进程已经退出
if($res == -1 || $res > 0)
unset(
$childs[$key]);
}

sleep(1);
}
?>
renmengyang567 at gmail dot com
5 年前
<?php

declare(ticks = 1);
function
zp_handler($signal) {
$id = pcntl_waitpid(-1, $status, WNOHANG);
if (
pcntl_wifexited($status))
{
printf("已移除子进程 id: %d \n",$id);
printf("子进程状态: %d \n",pcntl_wexitstatus($status));
}
}

//pcntl_signal_dispatch();
pcntl_signal(SIGCHLD, "zp_handler");
//pcntl_signal_dispatch();
//

$pid = pcntl_fork();
if (
$pid == 0)
{
print
"#1 您好,我是子进程".PHP_EOL;
sleep(3);
return
10;
}
else
{
print
"#1 父进程 id:".$pid.PHP_EOL;
$pid = pcntl_fork();
if (
$pid == 0)
{ print
"#2 您好,我是子进程".PHP_EOL;
sleep(10);
exit(
20);
}
else
{
print
"#2 父进程 id:".$pid.PHP_EOL;
for (
$i=0; $i <10 ; $i++) {
print
"等待..".PHP_EOL;
sleep(10);
}
}
}
?>
To Top