长时间运行的脚本的 symfony 执行

Symfony execution of long running script

本文关键字:执行 symfony 脚本 长时间 运行      更新时间:2023-10-16

我正在使用Symfony2,我想运行一个用C++编写的长脚本(例如60分钟)。

现在我通过shell_exec()来做到这一点:

$pid = shell_exec('nohup my/program/written/in/c++.out some arguments > /dev/null 2>/dev/null & echo $!');

如果我不断刷新页面,脚本运行良好,但是如果我使用 AFK,脚本将随着 PHP 服务器的进程 (/usr/bin/php-cgi) 终止。

有没有办法将程序与PHP服务器进程隔离C++?使用 nohup 时,进程的 ppid = 1,因此应该将其隔离,但事实并非如此。

你可以

看看Symfony进程组件: http://symfony.com/doc/current/components/process.html

$process = new Process('nohup my/program/written/in/c++.out some arguments');
$process->run();

您将能够运行您的进程。

你可以创建 symfony2 控制台命令 "myapp:my-command-name" 来运行你的 c++ 命令

class MyStandaloneCommand extends ContainerAwareCommand
{
    protected function configure()
    {
        $this->setName('myapp:my-command-name')
            ->setDescription('Will run standalone c++')
            ->addArgument('arg1', InputArgument::REQUIRED, 'Some arg');
    }
    protected function execute(InputInterface $input, OutputInterface $output)
    {   
        $arg1 = $input->getArgument('arg1');
        $result = shell_exec('nohup my/program/written/in/c++.out '.$arg1.' 2>&1');
        $output->writeln('My cool command is started');
        return true;
    }
}

然后使用 JMSJobBundle
http://jmsyst.com/bundles/JMSJobQueueBundle/master/installation

您可以在其中创建控制台命令的队列,如下所示:

class HomeController ... {
 // inject service here
 private $cronJobHelper;
 // inject EM here
 private $em;
public function indexAction(){
 $job = $this->cronJobHelper->createConsoleJob('myapp:my-command-name', $event->getId(), 10);
        $this->em->persist($job);
 $this->em->persist($job);
$this->em->flush();
}

use JMSJobQueueBundleEntityJob;
class CronJobHelper{
    public function createConsoleJob($consoleFunction, $params, $delayToRunInSeconds, $priority = Job::PRIORITY_DEFAULT, $queue = Job::DEFAULT_QUEUE){
        if(!is_array($params)){
            $params = [$params];
        }
        $job = new Job($consoleFunction, $params, 1, $queue, $priority);
        $date = $job->getExecuteAfter();
        $date = new DateTime('now');
        $date->setTimezone(new DateTimeZone('UTC')); //just in case
        $date->add(new DateInterval('PT'.$delayToRunInSeconds.'S')); 
        $job->setExecuteAfter($date);
        return $job;
    }
}