目标: 我的脚本将在表单提交时下载一个远程文件,因为文件可能很大,我想分出一个过程并让用户继续他/她的生活。
命令示例:
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
尝试方法:
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;
}
我确实得到了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 :(得分:3)
虽然不是直接答案,但以下链接可能会帮助您完成此任务:
作为PHP本机pctl函数的替代方法,请考虑使用Gearman:
Gearman提供了一个通用的应用程序框架,可以将工作分配给更适合工作的其他机器或进程。它允许您并行工作,负载均衡处理以及在语言之间调用函数。它可用于各种应用程序,从高可用性网站到数据库复制事件的传输。
答案 1 :(得分:0)
答案 2 :(得分:0)
尝试添加“echo $!”与启动的后台进程相同的执行流程。
即。这样的事情: shell_exec(“$ command& echo $!”);