PHP的進程控制支持實現了Unix方式的進程創建, 程序執行, 信號處理以及進程的中斷。 進程控制不能被應用在Web服務器環境,當其被用於Web服務環境時可能會帶來意外的結果。
目前該擴展只能運行在*unix下,PCNTL現在使用了ticks作爲信號處理的回調機制,ticks在速度上遠遠超過了之前的處理機制。 這個變化與“用戶ticks”遵循了相同的語義。您可以使用declare() 語句在程序中指定允許發生回調的位置。這使得我們對異步事件處理的開銷最小化。在編譯PHP時 啓用pcntl將始終承擔這種開銷,不論您的腳本中是否真正使用了pcntl。
在學習PCNTL前,請確保PHP已經安裝了該擴展:
[root@laiji ~]# php -m|grep pcntl pcntl
學習實例:
<?php $pid=pcntl_fork();//在當前進程當前位置產生分支(子進程) if($pid==-1){ die('could not [email protected]');//無法創建子進程 }elseif($pid){//當PID大於0時,進入父進程處理邏輯 var_dump("parent"); var_dump($status,'status'); }else{//當PID等於0時,進入子進程處理邏輯 for($i=0;$i<50;$i++){ echo $i.'-'; } var_dump("child exit"); exit();//最好加上這句,否則子進程還會往下走 } //最後運行 echo "\n---------------\n"; for($j=0;$j<200;$j++){ echo $j."+"; } ?>
爲什麼會需要進行PID值的判斷呢?是因爲在pcntl_fork()運行之後,fork是創建了一個子進程,父進程和子進程 都從fork的位置開始向下繼續執行,不同的是父進程執行過程中,得到的fork返回值爲子進程 號,而子進程得到的是0。換句話說,就是產生子進程與父進程都會繼續執行後面相同的代碼,因此需要區別當前運行的進程屬性。
我們運行後發現,先會進來執行parent分支,但是對於哪個進程先結束卻是依賴於LINUX系統的進程運行過程,你可以爲進程設置優先級(pcntl_setpriority — 修改任意進程的優先級)。常常我們父進程需要依賴子進程都運行完成後才能結束,因此在父進程需要等待子進程,使用的PCNTL函數:pcntl_wait — 等待或返回fork的子進程狀態。
父進程依賴子進程完成的代碼爲:
<?php $pid=pcntl_fork(); if($pid==-1){ die('could not fork'); }elseif($pid){ var_dump("parent"); pcntl_wait($status); var_dump($status,'status'); }else{ #pcntl_alarm(3); sleep(15); var_dump('chlid'); for($i=0;$i<50;$i++){ echo $i.'-'; } var_dump("child exit"); exit(); } echo "\n---------------\n"; for($j=0;$j<200;$j++){ echo $j."+"; } ?>
運行後,在父進程需要等待15秒後的子進程完成了,纔會運行到最後一步。