Скрипт запуска PHP после завершения фонового процесса?

#php #process #background-process #pdf2swf

#php #процесс #фоновый процесс #pdf2swf

Вопрос:

Я конвертирую PDF с помощью PDF2SWF и индексирую с помощью XPDF .. с помощью exec .. только для этого требуется действительно большое время выполнения.

Возможно ли запустить его как фоновый процесс, а затем запустить скрипт по завершении преобразования?

Ответ №1:

как правило, php не реализует потоки.

Но есть ZF-класс, который может подойти для вас:

http://framework.zend.com/manual/en/zendx.console.process.unix.overview.html

ZendX_Console_Process_Unix позволяет разработчикам создавать объект как новый процесс и таким образом выполнять несколько задач параллельно в консольных средах. Из-за своей специфики он работает только на системах на базе nix, таких как Linux, Solaris, Mac / OSx и подобных. Кроме того, для запуска этого компонента требуются модули shmop_, pcntl_* и posix_*. Если одно из требований не выполнено, после создания экземпляра компонента будет выдано исключение.

подходящий пример:

 class MyProcess extends ZendX_Console_Process_Unix
{
    protected function _run()
    {
        // doing pdf and flash stuff
    }
}

$process1 = new MyProcess();
$process1->start();

while ($process1->isRunning()) {

    sleep(1);

}

echo 'Process completed';
  

.

Комментарии:

1. Только что попробовал, и кажется, что этот компонент всегда зависает… isRunning всегда выполняется даже после завершения процесса.

Ответ №2:

Попробуйте использовать popen() вместо exec().

Этот взлом будет работать при любой стандартной установке PHP, даже в Windows, никаких дополнительных библиотек не требуется. Вы не можете реально контролировать все аспекты процессов, которые вы запускаете таким образом, но иногда этого достаточно:

 $p1 = popen("/bin/bash ./some_shell_script.sh argument_1","r");
$p2 = popen("/bin/bash ./some_other_shell_script.sh argument_2","r");
$p2 = popen("/bin/bash ./yet_other_shell_script.sh argument_3","r");
  

Три созданных сценария оболочки будут выполняться одновременно, и до тех пор, пока вы не выполните pclose($p1) (или $ p2, или $ p3) или не попытаетесь прочитать из любого из этих каналов, они не заблокируют выполнение вашего PHP.

Когда вы закончите с другими вашими делами (теми, которые вы делаете со своим PHP-скриптом), вы можете вызвать pclose() в каналах, и это приостановит выполнение вашего скрипта до завершения процесса, который вы закрываете. Тогда ваш скрипт может сделать что-то еще.

Обратите внимание, что ваш PHP не завершит работу или не умрет (), пока эти скрипты не завершатся. Завершение скрипта или вызов die() заставят его подождать.

Комментарии:

1. На самом деле теперь я вижу, что это действительно работает .. если PHP, который я выполняю, не содержит exec X_x, тогда он не работает, и в моих журналах apache ничего нет… Если я делаю что-то вроде fwrite, это действительно работает.

Ответ №3:

Если вы запускаете его из командной строки, вы можете запустить php-процесс с помощью pcntl_fork

Существуют также классы-демоны, которые выполняли бы тот же трюк:

http://pear.php.net/package/System_Daemon

 $pid = pcntl_fork();
if ($pid == -1) {
     die('could not fork');
} else if ($pid) {

     //We are the parent, exit
exit();

} else {

// We are the child, do something interesting then call the script at the end.

}