多进程实例
支持设置最大子进程数;
Master-Worker结构:Worker挂掉,Master进程会重新创建一个;
<?php
$pids = []; //存储子进程pid
$MAX_PROCESS = 3;//最大进程数
$pid = pcntl_fork();
if($pid < 0){
exit("fork fail\n");
}elseif($pid > 0){
////父进程退出,子进程不是进程组长,以便接下来顺利创建新会话
exit(0);
}else{
// 最重要的一步,创建一个新的会话,脱离原来的控制终端
if (posix_setsid() == -1) {
die("could not detach from terminal");
}
$id = getmypid();
echo time()." Master process, pid {$id}\n";
// 修改当前进程的工作目录,由于子进程会继承父进程的工作目录,修改工作目录以释放对父进程工作目录的占用。
chdir('/');
/*
* 通过上一步,我们创建了一个新的会话组长,进程组长,且脱离了终端,但是会话组长可以申请重新打开一个终端,为了避免
* 这种情况,我们再次创建一个子进程,并退出当前进程,这样运行的进程就不再是会话组长。
*/
for($i=0; $i<$MAX_PROCESS;$i++){
start_worker_process();
}
//Master进程等待子进程退出,必须是死循环
while(1){
foreach($pids as $pid){
if($pid){
$res = pcntl_waitpid($pid, $status, WNOHANG);
if ( $res == -1 || $res > 0 ){
echo time()." Worker process $pid exit, will start new... \n";
start_worker_process();
unset($pids[$pid]);
}
}
}
}
}
/**
* 创建worker进程
*/
function start_worker_process(){
global $pids;
$pid = pcntl_fork();
if($pid <0){
exit("fork fail\n");
}elseif($pid > 0){
$pids[$pid] = $pid;
// exit; //此处不可退出,否则Master进程就退出了
}else{
//实际代码
$id = getmypid();
$rand = rand(1,3);
echo time()." Worker process, pid {$id}. run $rand s\n";
while(1){
sleep($rand);
}
}
}本文为崔凯原创文章,转载无需和我联系,但请注明来自冷暖自知一抹茶ckhttp://www.cksite.cn