對編程的理解,應該到深刻到操做系統級別。進程控制,我一直都沒有接觸,感受好高端,今天啃了一下pcntl擴展的最簡單的兩個函數,有點心得,記錄一下吧,歡迎拋磚。
新建代碼文件 pcntl_wait.php,以下: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 \n"; } 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 \n"; //exit; //sleep(2); } $i++; }
php -f pcntl_wait.php 運行結果以下:shell
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.net
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=1code
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,最後命令結束。