以实例全面讲解PHP中多进程编程的相关函数的使(4)

<?php //..... //需要安装pcntl的php扩展,并加载它 if(function_exists("pcntl_fork")){ //生成第一个子进程 $pid = pcntl_fork(); //$pid即所产生的子进程id if($pid == -1){ //子进程fork失败 die('could not fork'); }else{ if($pid){ //父进程code sleep(5); //等待5秒 exit(0); //或$this->_redirect('https://www.jb51.net/'); }else{ //第一个子进程code //产生孙进程 if(($gpid = pcntl_fork()) < 0){ ////$gpid即所产生的孙进程id //孙进程产生失败 die('could not fork'); }elseif($gpid > 0){ //第一个子进程code,即孙进程的父进程 $status = 0; $status = pcntl_wait($status); //阻塞子进程,并返回孙进程的退出状态,用于检查是否正常退出 if($status ! = 0) file_put_content('filename', '孙进程异常退出'); //得到父进程id //$ppid = posix_getppid(); //如果$ppid为1则表示其父进程已变为init进程,原父进程已退出 //得到子进程id:posix_getpid()或getmypid()或是fork返回的变量$pid //kill掉子进程 //posix_kill(getmypid(), SIGTERM); exit(0); }else{ //即$gpid == 0 //孙进程code //.... //结束孙进程(即当前进程),以防止生成僵尸进程 if(function_exists('posix_kill')){ posix_kill(getmypid(), SIGTERM); }else{ system('kill -9'. getmypid()); } exit(0); } } } }else{ // 不支持多进程处理时的代码在这里 } //..... ?>

怎样产生僵尸进程的
一个进程在调用exit命令结束自己的生命的时候,其实它并没有真正的被销毁,而是留下一个称为僵尸进程(Zombie)的数据结构(系统调用exit,它的作用是使进程退出,但也仅仅限于将一个正常的进程变成一个僵尸进程,并不能将其完全销毁)。在Linux进程的状态中,僵尸进程是非常特殊的一种,它已经放弃了几乎所有内存空间,没有任何可执行代码,也不能被调度,仅仅在进程列表中保留一个位置,记载该进程的退出状态等信息供其他进程收集,除此之外,僵尸进程不再占有任何内存空间。它需要它的父进程来为它收尸,如果他的父进程没安装SIGCHLD信号处理函数调用wait或waitpid()等待子进程结束,又没有显式忽略该信号,那么它就一直保持僵尸状态,如果这时父进程结束了,那么init进程自动会接手这个子进程,为它收尸,它还是能被清除的。但是如果如果父进程是一个循环,不会结束,那么子进程就会一直保持僵尸状态,这就是为什么系统中有时会有很多的僵尸进程。

任何一个子进程(init除外)在exit()之后,并非马上就消失掉,而是留下一个称为僵尸进程(Zombie)的数据结构,等待父进程处理。这是每个子进程在结束时都要经过的阶段。如果子进程在exit()之后,父进程没有来得及处理,这时用ps命令就能看到子进程的状态是”Z”。如果父进程能及时 处理,可能用ps命令就来不及看到子进程的僵尸状态,但这并不等于子进程不经过僵尸状态。

如果父进程在子进程结束之前退出,则子进程将由init接管。init将会以父进程的身份对僵尸状态的子进程进行处理。

另外,还可以写一个php文件,然后在以后台形式来运行它,例如:


<?php //Action代码 public function createAction(){ //.... //将args替换成要传给insertLargeData.php的参数,参数间用空格间隔 system('php -f insertLargeData.php ' . ' args ' . '&'); $this->redirect('https://www.jb51.net/'); } ?>

然后在insertLargeData.php文件中做数据库操作。也可以用cronjob + php的方式实现大数据量的处理。

如果是在终端运行php命令,当终端关闭后,刚刚执行的命令也会被强制关闭,如果你想让其不受终端关闭的影响,可以使用nohup命令实现:


<?php //Action代码 public function createAction(){ //.... //将args替换成要传给insertLargeData.php的参数,参数间用空格间隔 system('nohup php -f insertLargeData.php ' . ' args ' . '&'); $this->redirect('https://www.jb51.net/'); } ?>

你还可以使用screen命令代替nohup命令。

您可能感兴趣的文章:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/775919cecf5b781c83274b5a376331e2.html