【问题标题】:Symfony Process - Background tasksSymfony 进程 - 后台任务
【发布时间】:2017-04-05 15:31:50
【问题描述】:

我想用 Symfony Process 组件运行一个孤立的后台进程。我不能使用 kernel.terminate 事件。 这是我试图做的:

这是我要运行的过程:

// script.php
$f = fopen('test'.uniqid().'.txt', 'w');
for ($i = 0; $i < 1000; $i++) {
    fwrite($f, "Line $i \n");
    sleep(2);
}
fclose ($f);

这是我想运行我的进程的脚本:

// test.php
$command = "php script.php > /dev/null 2>&1 &";

$p = new \Symfony\Component\Process\Process($command);
$p->start();
echo $p->getPid()."\n";

问题是test.php 终止后,script.php 不起作用。主脚本的终止会杀死所有子进程。是否可以让孤立的进程与 Symfony 进程一起运行?

【问题讨论】:

  • 在我回答这个问题之前,你首先要达到什么目的

标签: php symfony proc-open symfony-process


【解决方案1】:

最简单的方法,不要使用进程组件并回退到php exec:

http://php.net/manual/de/function.exec.php

exec('php script.php > /dev/null 2>&1 &');

要获得更可靠的解决方案,请考虑类似计划和 crontab 执行命令,以便在需要启动进程时启动进程。

【讨论】:

  • 我相当肯定这将与 OP 已经在做同样的事情。
  • 不是。 Process 组件使用 proc_open ,它实际上为由 Process 组件监视的输出返回一个资源。 exec 工作方式不同,一劳永逸(在执行命令末尾给出最后一个&amp;
  • 进程库臃肿无用。浪费了很多时间玩它,最终得到了旧的好 exec()。
【解决方案2】:

您可以将at (atd) 或cron 与自定义队列一起使用。 PHP 调用同步命令,该命令将所需命令排入队列以供以后执行。 at 是 Unix 系统中相当强大的标准组件。您只需运行 at now + 10 min 并将命令推送到其标准输入,然后 atd 守护程序将在 10 分钟内运行您的命令。

如果您希望直接从 PHP 运行命令,请尝试添加 shell:new Process('/bin/sh -c "php script.php &amp;"')。我不确定 Process 类究竟是如何调用命令的,但如果 & 不起作用,则在两者之间再添加一个 shell 就可以解决问题(这就是 exec() 所做的)。

【讨论】: