PHP fork限制任务执行 [英] PHP fork limit childs in the task

查看:48
本文介绍了PHP fork限制任务执行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

*答案中的解决方案 *

* SOLUTION IN THE ANSWER BELOW *

我在multifork php脚本中限制子项时遇到问题...似乎最后一个子项永无休止...我真的很累,无法找到错误,请您帮忙吗?它通常不会结束...

I got a problem with limiting childs in the multifork php script... Seems like last child never ends... I'm really tired and can't find the error, could You please help? It does not end most of times...

<?php
declare(ticks = 1);

$max=5;
$child=0;

function sig_handler($signo) {
    global $child;
    switch ($signo) {
        case SIGCHLD:
        $child -= 1;
        echo "[-]";
    }
}

pcntl_signal(SIGCHLD, "sig_handler");

$found = array(1,2,3,4,5,6,7,8,9,10,11,12);

echo "LETS GO!\n";

foreach($found as $item){

            while ($child >= $max) {
            sleep(1);
        }

        $child++;
        echo "[+]";
        $pid=pcntl_fork();

        if($pid){
        }else{ // CHILD
            sleep(rand(1,5));
            echo "[~]";
            exit(0);
        }

}

while($child != 0){
    echo "($child)";
    sleep(1);
}

echo "THE END.\n"

?>

大多数情况下的结果是:

Result most times is:

[+][+][+][+][+][~][-][+][~][-][+][~][-][+][~][-][+][~][-][+][~][-][+][~][~][~][-][+]    (5)[-](4)(4)[~][-](3)[~][-](2)(2)[~](2)[-](1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)... etc etc ...

好像最后一个孩子根本没有结束,或者至少它没有触发信号处理程序...

Seems like last child does not end at all or at least it doesnt trigger sig handler...

  • [+]<-分叉前-计数:12
  • [〜]<-即将退出孩子之前-计数:12
  • [-]<-退出子程序后的信号处理程序-计数:11

帮助?

PS.奇怪的是,有时它确实会结束.

PS. The weird thing is that it sometimes does end.

推荐答案

确定了解决方案:

function sig_handler($signo){
  global $child;
  switch ($signo) {
    case SIGCLD:
      while( ( $pid = pcntl_wait ( $signo, WNOHANG ) ) > 0 ){
        $signal = pcntl_wexitstatus ($signo);
        $child -= 1;
        echo "[-]";       
      }
    break;
  }
}

问题出在UNIX系统上处理信号的方式上.在相似时间内发送的所有信号都被分组为一个.上面的功能解决了该问题.而且,不仅如此……当孩子立即退出时,它不再出现segfault(在某些PHP配置/版本中为"zend_mm_heap损坏"错误).在以前的案例中也是如此.

The problem was in the way of handling signals on UNIX systems. All sigs sent in similar time are being grouped to one. The function above fixes that problem. And not only that one... when child exits immediately, it doesn't segfault ("zend_mm_heap corrupted" error in some PHP configurations/versions) anymore. And it did in previous case.

PS.我应该删除这个问题,但是我将解决方案留给每个遇到类似问题的人,因为PHP脚本中的多线程对于某些任务非常有用.

PS. I should delete this question, but I will leave the solution for everyone experiencing similar problems as multithreading in PHP scripts is very useful for some tasks.

这篇关于PHP fork限制任务执行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆