php进程分叉并获取子进程ID

时间:2010-03-07 11:58:33

标签: php multithreading nginx fork

目标: 我的脚本将在表单提交时下载一个远程文件,因为文件可能很大,我想分出一个过程并让用户继续他/她的生活。

命令示例:

wget -q --limit-rate = 1k --tries = 10“http://helios.gsfc.nasa.gov/image_euv_press.jpg” - O /web/assets/content/image/image_euv_press.jpg

尝试方法:

  1. pcntl forking,

        $pid = pcntl_fork();
    
        if ( $pid == -1 ) {
            exit;
        } else if ( $pid ) {
            //We are the parent process, the pid is child pid right?
    
            return $pid;
        } else {
            // We are the child process
    
            exec($command.' > /dev/null');
            // > /dev/null &
    
            posix_kill(getmypid(),9);
            return;
        }
    
  2. 我确实得到了PID但是然后存在分叉进程变成僵尸的风险,因为我使用的是nginx - > php-fpm(测试并确认,运行了好几次已经失效的php-fpm进程),我不得不重启服务器只是为了消灭僵尸,这会让我陷入PID耗尽攻击? (我猜)

    1. 后台流程:

              exec($command . ' > /dev/null &');//background process
          $proc = passthru ("ps aux | grep '$command'");//search for the command
          echo var_dump($proc);
          $pid = (int)(next(explode(' ',$proc)));//parse the pid (not implemented)
      
    2. 问题: 后台进程方法有效,但它不干净,是否有更好的方法来分离下载进程并获取该wget命令PID以便我可以在以后杀死它?

      我试过回复$!在执行exec之后只是为了得到PID而exec('echo $!')并没有返回任何东西,我认为这是因为每个exec都是一个不同的“空间”

      我添加'> / dev / null 2> / dev / null&'在我终端上的命令结束时它会返回类似于:[3] 30751,但是通过php exec,没有办法捕获返回的PID。

      谢谢。

3 个答案:

答案 0 :(得分:3)

虽然不是直接答案,但以下链接可能会帮助您完成此任务:

作为PHP本机pctl函数的替代方法,请考虑使用Gearman

  

Gearman提供了一个通用的应用程序框架,可以将工作分配给更适合工作的其他机器或进程。它允许您并行工作,负载均衡处理以及在语言之间调用函数。它可用于各种应用程序,从高可用性网站到数据库复制事件的传输。

答案 1 :(得分:0)

尝试以下命令:

exec("ps -C $command -o pid=", $pids);

但我建议你使用Zend Server Job Queue,这是为了实现这些目标。

答案 2 :(得分:0)

尝试添加“echo $!”与启动的后台进程相同的执行流程。

即。这样的事情:   shell_exec(“$ command& echo $!”);