PHP Conference Japan 2024

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,
    陣列 &$resource_usage = []
): 整數

暫停目前行程的執行,直到由 process_id 參數指定的子行程結束,或者直到收到一個會終止目前行程或呼叫訊號處理函式的訊號。

如果在呼叫時,process_id 所請求的子行程已經結束(所謂的「殭屍」行程),則此函式會立即返回。子行程使用的任何系統資源都會被釋放。請參閱您系統的 waitpid(2) 線上手冊頁面,以了解 waitpid 在您系統上的具體運作方式。

參數

process_id

process_id 的值可以是以下其中之一

process_id 的可能值
< -1 等待行程群組 ID 等於 process_id 絕對值的任何子行程。
-1 等待任何子行程;這與 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 的值是以下兩個或多個全域常數進行 OR 運算的結果

flags 的可能值
WNOHANG 如果沒有子行程結束,則立即返回。
WUNTRACED 返回已停止且狀態尚未回報的子行程。

回傳值

pcntl_waitpid() 返回結束的子行程的行程 ID,如果發生錯誤則返回 -1,如果使用了 WNOHANG 且沒有可用的子行程則返回 0。

另請參閱

新增註解

使用者貢獻的註解 3 則註解

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,因為內建的處理程式會先取得它。
0
fx4084 at gmail dot com
10 年前
<?php
$childs
= array();

// 產生一些行程。
for($i = 0; $i < 10; $i++) {
$pid = pcntl_fork();
if(
$pid == -1)
die(
'無法產生子行程');

if (
$pid) {
echo
"父行程 \n";
$childs[] = $pid;
} else {
// 睡眠 $i+1 (秒)。子行程可以取得這個參數($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);
}
?>
-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