這篇文章主要介紹了關於PHP的pcntl進程控制之pcntl_wait,有着一定的參考價值,現在分享給大家,有需要的朋友可以參考一下
pcntl_wait 簡介
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# 來源官方
pcntl_wait — 等待或返回fork的子進程狀態
int pcntl_wait ( int &$status [, int $options = 0 ] )
wait函數刮起當前進程的執行直到一個子進程退出或接收到一個信號要求中斷當前進程或調用一個信號處理函數。 如果一個子進程在調用此函數時已經退出(俗稱僵屍進程),此函數立刻返回。子進程使用的所有系統資源將 被釋放。關於wait在您系統上工作的詳細規范請查看您系統的wait(2)手冊。
Note:
這個函數等同於以-1作為參數pid 的值並且沒有options參數來調用pcntl_waitpid() 函數。
參數
status
pcntl_wait()將會存儲狀態信息到status 參數上,這個通過status參數返回的狀態信息可以用以下函數 pcntl_wifexited(), pcntl_wifstopped(), pcntl_wifsignaled(), pcntl_wexitstatus(), pcntl_wtermsig()以及 pcntl_wstopsig()獲取其具體的值。
options
如果您的操作系統(多數BSD類系統)允許使用wait3,您可以提供可選的options 參數。如果這個參數沒有提供,wait將會被用作系統調用。如果wait3不可用,提供參數 options不會有任何效果。options的值可以是0 或者以下兩個常量或兩個常量“或運算”結果(即兩個常量代表意義都有效)。
options可用值
WNOHANG 如果沒有子進程退出立刻返回。
WUNTRACED 子進程已經退出並且其狀態未報告時返回。
返回值
pcntl_wait()返回退出的子進程進程號,發生錯誤時返回-1,如果提供了 WNOHANG作為option(wait3可用的系統)並且沒有可用子進程時返回0。
|
測試代碼
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
<?php
if (strtolower(php_sapi_name()) != 'cli') {
die("請在cli模式下運行");
}
$index = 0;
$loop = 1;
while ($index < $loop) {
echo "當前進程:" . getmypid() . PHP_EOL;
$pid = pcntl_fork();
if ($pid == -1) {
die('進程fork失敗');
} else if ($pid) {
pcntl_wait($status);
$child_id = $pid;
$pid = posix_getpid();
$ppid = posix_getppid();
$time = microtime(true);
echo "我是父進程,fork的子進程id: {$child_id};當前進程id:{$pid};父進程id:{$ppid}; 當前index:{$index}; 當前時間:{$time}".PHP_EOL;
} else {
$cid = $pid;
$pid = posix_getpid();
$ppid = posix_getppid();
$myid = getmypid();
$time = microtime(true);
echo "我是子進程,當前進程id:{$pid};父進程id:{$ppid}; 當前index:{$index}; 當前時間:{$time}".PHP_EOL;
}
$index++;
}
|
loop = 1 執行結果
| 1 2 3 4 5 |
當前進程:16604
我是子進程,當前進程id:16605;父進程id:16604; 當前index:0; 當前時間:1528696774.1978
我是父進程,fork的子進程id: 16605;當前進程id:16604;父進程id:15128; 當前index:0; 當前時間:1528696774.2032
|
loop = 2 執行結果
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
當前進程:16613
我是子進程,當前進程id:16614;父進程id:16613; 當前index:0; 當前時間:1528696781.4751
當前進程:16614
我是子進程,當前進程id:16615;父進程id:16614; 當前index:1; 當前時間:1528696781.4756
我是父進程,fork的子進程id: 16615;當前進程id:16614;父進程id:16613; 當前index:1; 當前時間:1528696781.4802
我是父進程,fork的子進程id: 16614;當前進程id:16613;父進程id:15128; 當前index:0; 當前時間:1528696781.4858
當前進程:16613
我是子進程,當前進程id:16616;父進程id:16613; 當前index:1; 當前時間:1528696781.4863
我是父進程,fork的子進程id: 16616;當前進程id:16613;父進程id:15128; 當前index:1; 當前時間:1528696781.4913
|
loop = 3 執行結果
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
當前進程:16625
我是子進程,當前進程id:16626;父進程id:16625; 當前index:0; 當前時間:1528696787.3334
當前進程:16626
我是子進程,當前進程id:16627;父進程id:16626; 當前index:1; 當前時間:1528696787.3338
當前進程:16627
我是子進程,當前進程id:16628;父進程id:16627; 當前index:2; 當前時間:1528696787.3345
我是父進程,fork的子進程id: 16628;當前進程id:16627;父進程id:16626; 當前index:2; 當前時間:1528696787.3391
我是父進程,fork的子進程id: 16627;當前進程id:16626;父進程id:16625; 當前index:1; 當前時間:1528696787.3434
當前進程:16626
我是子進程,當前進程id:16629;父進程id:16626; 當前index:2; 當前時間:1528696787.3441
我是父進程,fork的子進程id: 16629;當前進程id:16626;父進程id:16625; 當前index:2; 當前時間:1528696787.3496
我是父進程,fork的子進程id: 16626;當前進程id:16625;父進程id:15128; 當前index:0; 當前時間:1528696787.3543
當前進程:16625
我是子進程,當前進程id:16630;父進程id:16625; 當前index:1; 當前時間:1528696787.3548
當前進程:16630
我是子進程,當前進程id:16631;父進程id:16630; 當前index:2; 當前時間:1528696787.3555
我是父進程,fork的子進程id: 16631;當前進程id:16630;父進程id:16625; 當前index:2; 當前時間:1528696787.3599
我是父進程,fork的子進程id: 16630;當前進程id:16625;父進程id:15128; 當前index:1; 當前時間:1528696787.3643
當前進程:16625
我是子進程,當前進程id:16632;父進程id:16625; 當前index:2; 當前時間:1528696787.3649
我是父進程,fork的子進程id: 16632;當前進程id:16625;父進程id:15128; 當前index:2; 當前時間:1528696787.3697
|
總結
1.從執行的多次結果得知,程序從外到內創建fork。然后再從內最后一次fork開始退出
2.如一次fork之后,程序的父進程因pcntl_wait阻塞,然后等待本次fork的子進程退出,然后相應的子進程的父進程執行邏輯並退出
3.然后執行本子進程的父進程依次循環2的邏輯退出,最終結束總進程