1

私は 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) のプロセスで終了します。

C++ プログラムを PHP サーバープロセスから分離する方法はありますか? nohup の場合、プロセスは ppid = 1 であるため、分離する必要がありますが、そうではありません。

4

2 に答える 2

2

Symfony Process Component を見ることができます: http://symfony.com/doc/current/components/process.html

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

プロセスを実行できるようになります。

于 2015-04-20T14:43:35.280 に答える
0

C++ コマンドを実行する symfony2 コンソール コマンド "myapp:my-command-name" を作成できます。

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 JMS\JobQueueBundle\Entity\Job;

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;
    }
}
于 2015-04-20T15:05:43.173 に答える