#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.
}