pcntl_waitpid
等待或返回fork的子進程狀態。
多進程的主進程創建了子進程,那主進程如何確認子進程的狀態呢。 假如主進程需要根據子進程的狀態做不同的處理呢, 這里的狀態包括子進程被kill掉,或變成僵屍進程等。 pcntl_waitpid就可以獲取子進程的狀態碼, 通過這個狀態碼, 就可知道子進程處於什么狀態
他的用法:
int pcntl_waitpid ( int $pid , int &$status [, int $options = 0 ] )
返回的值可以是-1,0或者 >0的值, 如果是-1, 表示子進程出錯, 如果>0表示子進程已經退出且值是退出的子進程pid,至於如何退出, 可以通過$status狀態碼反應。 那什么時候返回0呢, 只有在option
參數為 WNOHANG
且子進程正在運行時0, 也就是說當設置了options=WNOHANG
時, 如果子進程還沒有退出, 此時pcntl_waitpid
就會返回0
另外, 如果不設置這個參數為WNOHANG
, pcntl_waitpid
就會阻塞運行
, 直到子進程退出, 至於option
的另外一個值WUNTRACED
, 暫未理解, 不表
那么如何根據$status(狀態碼)判斷進程是如何退出呢, 如下(參數都是$status)
pcntl_wifexited
這個函數可以根據$status 判斷進程是否正常退出, 何為正常退出, 比如exit
pcntl_wexitstatus
這個函數僅在pcntl_wifexited
返回True(即正常退出)時有效, 且返回子進程退出的返回狀態碼, 這個返回狀態碼可以通過exit($s)的參數($s必須為整數時)定義
pcntl_wifsignaled
檢查子進程狀態碼是否代表由於某個信號而中斷, 比如是不是我們給他發送了term, int 等信號了
pcntl_wexitstatus
假如是發送信號而導致子進程中斷, 那么這個信號是什么信號呢, 這個函數就是獲取這個信號的
pcntl_wifstopped
僅當option選項為WUNTRACED時有效, 未理解, 不表
pcntl_wtermsig
同上
綜合實例代碼:
$res = pcntl_waitpid($pid, $status, WNOHANG); //FileLog::log("pid is $pid; wait result is $res"); if($res == -1 || $res > 0){ if(!pcntl_wifexited($status)){ //進程非正常退出 FileLog::log("service stop unusally; pid is $pid"); }else{ //獲取進程終端的退出狀態碼; $code = pcntl_wexitstatus($status); FileLog::log("service stop code: $code;pid is $pid "); } if(pcntl_wifsignaled($status)){ //不是通過接受信號中斷 FileLog::log("service stop not by signal;pid is $pid "); }else{ $signal = pcntl_wtermsig($status); FileLog::log("service stop by signal $signal;pid is $pid"); } }
上面的這個代碼就通過根據pcntl_waitpid
的返回結果和狀態碼對子進程因為不同原因中斷做了不同的處理