2010-03-07 84 views
0

目标: 我的脚本将在表单提交时下载远程文件,因为该文件可能很大,我想分叉一个进程并让用户继续他/她的一生。一个命令的php进程分叉和获取子进程号

实施例:

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

方法尝试:

  1. 了pcntl分叉,

    $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; 
        } 
    

我确实得到了PID,但是然后存在分叉进程变成僵尸的风险,因为我使用nginx-> php-fpm(测试并确认,运行几次很多已失效的php-fpm进程),我将不得不重新启动服务器只是为了消除僵尸,这会使我陷入PID耗尽攻击? (我猜)

  • 后台进程:

     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) 
    
  • 问题: 后台处理方法的作品,但它不干净,有没有更好的办法分离一个进程下载并获得该wget命令PID,以便我可以在以后杀死它?

    我试过回显$!在执行exec以获得PID但是exec('echo $!')不返回任何内容后,我认为这是因为每个exec都是不同的“空间”

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

    谢谢。

    回答

    0

    试试下面的命令:

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

    但我建议你使用Zend Server Job Queue,其中存在这些目标。

    +0

    谢谢!这条线很棒! – wahyudinata 2010-03-07 23:38:48

    3

    虽然没有直接回答,下面的链接可以帮助你完成它:

    作为替代PHP的本地PCTL功能,可以考虑使用Gearman

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

    +0

    第一个链接似乎已损坏。 – 2012-10-22 04:37:25

    +0

    @JonathonHill固定。谢谢。 – Gordon 2012-10-22 07:19:45

    0

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

    I.e.像这样: shell_exec(“$ command & echo $!”);