對程式設計的理解,應該到深入到作業系統級別。程式控制,我一直都沒有接觸,感覺好高階,今天啃了一下pcntl擴充套件的最簡單的兩個函式,有點心得,記錄一下吧,歡迎拋磚。
新建程式碼檔案 pcntl_wait.php,如下:
$i = 0;
while($i < 2) {
$pid = pcntl_fork();
// 父程式和子程式都會執行以下程式碼
if ($pid == -1) { // 建立子程式錯誤,返回-1
die(`could not fork`);
} else if ($pid) {
// 父程式會得到子程式號,所以這裡是父程式執行的邏輯
pcntl_wait($status); // 父程式必須等待一個子程式退出後,再建立下一個子程式。
$cid = $pid; // 子程式的ID
$pid = posix_getpid(); // pid 與mypid一樣,是當前程式Id
$myid = getmypid();
$ppid = posix_getppid(); // 程式的父級ID
$time = microtime(true);
echo "I am parent cid:$cid myid:$myid pid:$pid ppid:$ppid i:$i $time
";
} else {
// 子程式得到的$pid 為0,所以這裡是子程式的邏輯
$cid = $pid;
$pid = posix_getpid();
$ppid = posix_getppid();
$myid = getmypid();
$time = microtime(true);
echo "I am child cid:$cid myid:$myid pid:$pid ppid:$ppid i:$i $time
";
//exit;
//sleep(2);
}
$i++;
}
php -f pcntl_wait.php 執行結果如下:
I am child cid:0 myid:6499 pid:6499 ppid:6498 i:0 1491394182.2065
I am child cid:0 myid:6500 pid:6500 ppid:6499 i:1 1491394182.2077
I am parent cid:6500 myid:6499 pid:6499 ppid:6498 i:1 1491394182.2143
I am parent cid:6499 myid:6498 pid:6498 ppid:3471 i:0 1491394182.2211
I am child cid:0 myid:6501 pid:6501 ppid:6498 i:1 1491394182.222
I am parent cid:6501 myid:6498 pid:6498 ppid:3471 i:1 1491394182.2302
為何是如上執行過程?
參考了PHP手冊和網友blog以上程式碼能夠迴圈產生子程式,並且父程式會阻塞等待子程式退出,這樣就產生了一個問題,父程式必須等待一個子程式退出後,再建立另外一個
個人分析如下:
1.執行shell命令(該程式ID是3471),生成主程式PID為6498
開始迴圈i=0
6498 此時的父程式
|fork
6499 父程式(6498阻塞),該子程式(6499)執行 ,輸出:child cid:0 myid:6499 pid:6499 ppid:6498 i:0 1491394182.2065
然後i++ i=1,再次迴圈
繼續迴圈i=1
6499 此時的父程式
|fork
6500 父程式(6499阻塞),該子程式(6500)執行,輸出:child cid:0 myid:6500 pid:6500 ppid:6499 i:1 1491394182.2077
然後i++ i=2,本次迴圈終止,回到其主程式6499
6499 解除阻塞,
此時i=1(因為阻塞時i=1),繼續執行 輸出:parent cid:6500 myid:6499 pid:6499 ppid:6498 i:1 1491394182.2143
然後i++ i=2,本次迴圈終止,回到其主程式6498
6498 解除阻塞,
此時i=0(因為阻塞時i=0),繼續執行,輸出:parent cid:6499 myid:6498 pid:6498 ppid:3471 i:0 1491394182.2211
然後i++ i=1,再次迴圈
繼續迴圈i=1
6498 此時的父程式
|fork
6501 父程式(6498阻塞),該子程式(6501)執行,輸出:child cid:0 myid:6501 pid:6501 ppid:6498 i:1 1491394182.222
然後i++ i=2,本次迴圈終止,回到其主程式6498
6498 解除阻塞
此時i=1(因為阻塞時為i=1),繼續執行,輸出:parent cid:6501 myid:6498 pid:6498 ppid:3471 i:1 1491394182.2302
然後i++ i=2,本次迴圈終止,回到其主程式3471,最後命令結束。