Symfony выполнение длинного скрипта

Я использую 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, поэтому он должен быть изолирован, но это не так.

1

Решение

Вы можете посмотреть на Компонент Symfony Process: http://symfony.com/doc/current/components/process.html

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

Вы сможете запустить свой процесс.

2

Другие решения

Вы можете создать консольную команду 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 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;
}
}
0

По вопросам рекламы [email protected]