php wait for,PHP: pcntl_wait - Manual

Using pcntl_fork() can be a little tricky in some situations.  For fast jobs, a child can finish processing before the parent process has executed some code related to the launching of the process.  The parent can receive a signal before it's ready to handle the child process' status.  To handle this scenario, I add an id to a "queue" of processes in the signal handler that need to be cleaned up if the parent process is not yet ready to handle them.

public$maxProcesses=25;

protected$jobsStarted=0;

protected$currentJobs= array();

protected$signalQueue=array();

protected$parentPID;

public function__construct(){

echo"constructed \n";$this->parentPID=getmypid();pcntl_signal(SIGCHLD, array($this,"childSignalHandler"));

}/**

* Run the Daemon

*/public functionrun(){

echo"Running \n";

for($i=0;$i<10000;$i++){$jobID=rand(0,10000000000000);$launched=$this->launchJob($jobID);

}//Wait for child processes to finish before exiting herewhile(count($this->currentJobs)){

echo"Waiting for current jobs to finish... \n";sleep(1);

}

}/**

* Launch a job from the job queue

*/protected functionlaunchJob($jobID){$pid=pcntl_fork();

if($pid== -1){//Problem launching the joberror_log('Could not launch new job, exiting');

returnfalse;

}

else if ($pid){// Parent process

// Sometimes you can receive a signal to the childSignalHandler function before this code executes if

// the child script executes quickly enough!

//$this->currentJobs[$pid] =$jobID;// In the event that a signal for this pid was caught before we get here, it will be in our signalQueue array

// So let's go ahead and process it now as if we'd just received the signalif(isset($this->signalQueue[$pid])){

echo"found$pidin the signal queue, processing it now \n";$this->childSignalHandler(SIGCHLD,$pid,$this->signalQueue[$pid]);

unset($this->signalQueue[$pid]);

}

}

else{//Forked child, do your deeds....$exitStatus=0;//Error code if you need to or whateverecho"Doing something fun in pid ".getmypid()."\n";

exit($exitStatus);

}

returntrue;

}

public functionchildSignalHandler($signo,$pid=null,$status=null){//If no pid is provided, that means we're getting the signal from the system.  Let's figure out

//which child process endedif(!$pid){$pid=pcntl_waitpid(-1,$status,WNOHANG);

}//Make sure we get all of the exited childrenwhile($pid>0){

if($pid&& isset($this->currentJobs[$pid])){$exitCode=pcntl_wexitstatus($status);

if($exitCode!=0){

echo"$pidexited with status ".$exitCode."\n";

}

unset($this->currentJobs[$pid]);

}

else if($pid){//Oh no, our job has finished before this parent process could even note that it had been launched!

//Let's make note of it and handle it when the parent process is ready for itecho"..... Adding$pidto the signal queue ..... \n";$this->signalQueue[$pid] =$status;

}$pid=pcntl_waitpid(-1,$status,WNOHANG);

}

returntrue;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值