php多進程編程實現與優化
阿新 • • 發佈:2018-05-28
exist RR 執行 erl php code trace HP void
PHP多進程API
創建子進程
@params void
@returns int
int pcntl_fork(void)
成功時,在父進程執行線程內返回產生的子進程PID,在子進程執行線程內返回0,失敗時,在父進程上下文返回-1,不會創建子進程,並且會引發一個php錯誤
獲取當前進程id
@params void
@returns int
int posix_getpid(void)
返回進程id,類型為整型
父進程等待子進程退出
@params $status
@params $option
@return bool
int pcntl_wait(int &$status[,int $options =0])
該函數等同於以-1作為參數pid的值並且沒有options參數來調用pcntl_waitpid()的函數
進程退出狀態
@params $status
@return bool
bool pcntl_wifexited(int $status)
進程退出碼
@params $status
@return int
int pcntl_wexitstatus(int $status)
簡單PHP多進程示例
function process_execute($input) {
$pid = pcntl_fork(); //創建子進程
if ($pid == 0) {//子進程
$pid = posix_getpid();
echo "* Process {$pid} was created, and Executed:\n\n";
eval($input); //解析命令
exit;
} else {//主進程
$pid = pcntl_wait($status, WUNTRACED); //取得子進程結束狀態
if (pcntl_wifexited( $status)) {
echo "\n\n* Sub process: {$pid} exited with {$status}";
}
}
通過調用php創建子進程接口完成一個子進程的創建,pcntl_fork返回值為0證明進入到子進程內,非0則進入到父進程內部,-1則父進程創建子進程失敗。
多個子進程初級版本示例
foreach ($clusterList as $key=>$value) {
$pid = pcntl_fork();//創建子進程
if($pid == 0) {//子進程
//do something
} else if($pid == -1) {
//fork error occured
} else {
pcntl_wait($status);
}
}
該實現方式主要邏輯為循環創建一個子進程,並且父進程等待子進程完成退出後,再繼續創建下一個子進程
缺點:無法真正體現多進程,實際上時串行的創建子進程
多個子進程優化版本示例
foreach ($clusterList as $key=>$value) {
$pid = pcntl_fork();//創建子進程
if($pid == 0) {//子進程
//do something
} else if($pid == -1) {
return false;
}
}
for (;;) {
$ret = pcntl_waitpid(-1,$status,WNOHANG);
if ($ret == -1) {
// error occured
} else if ($ret == 0) {
//all child are existed
break;
} else {
//check sub process exit status
$extFlag = pcntl_wifexited($status);
if(!$extFlag){
//exited unnormally
}else {
$extCode = pcntl_wexitstatus($status);
//exited normally
}
}
}
該邏輯通過for循環不斷獲取子進程的退出狀態,直到所有的子進程都退出,真正實現多進程處理。
php多進程編程實現與優化