Асинхронная оболочка exec в PHP

У меня есть сценарий PHP, который должен 9X_php5 вызывать сценарий оболочки, но не заботится 9X_php5 о выводе. Сценарий оболочки выполняет несколько 9X_asynchronously вызовов SOAP и выполняется медленно, поэтому 9X_php5 я не хочу замедлять выполнение PHP-запроса, пока 9X_async он ожидает ответа. Фактически, запрос PHP 9X_shell-command должен иметь возможность завершиться без 9X_shell-script завершения процесса оболочки.

Я изучил различные 9X_php5 функции exec(), shell_exec(), pcntl_fork() и т. д., но ни одна из них, похоже, не 9X_shell предлагает именно то, что я хочу. (Или, если 9X_shell-script они это сделают, мне непонятно как.) Есть 9X_php-fpm предложения?

212
1

  • Возможный дубликат [php выполняет фоновый процесс] (https://stackoverflow.com/questions/45953/php-execute-a-background-pr ...
13
Общее количество ответов: 13

Ответ #1

Ответ на вопрос: Асинхронная оболочка exec в PHP

Если он «не заботится о выводе», нельзя 9X_asynchronously ли вызвать exec для скрипта с & для фонового 9X_php-fpm процесса?

EDIT - включая то, что @ AdamTheHut прокомментировал 9X_asynchronously к этому сообщению, вы можете добавить это 9X_asynchronous к вызову exec:

" > /dev/null 2>/dev/null &"

Это перенаправит и stdio (первый >), и 9X_php.ini stderr (2>) на /dev/null и запустит их в фоновом режиме.

Есть 9X_shell-command и другие способы сделать то же самое, но 9X_asynchronous-processing это самый простой для чтения.


Альтернатива 9X_php-fpm указанному выше двойному перенаправлению:

" &> /dev/null &"

236
8

  • Фоновые сценарии будут убиты при перезапуске apache ... просто помните об этом для о ...

Ответ #2

Ответ на вопрос: Асинхронная оболочка exec в PHP

Я использовал для этого at, поскольку он действительно 9X_asynchronously запускает независимый процесс.


58
3

  • если пользователь, у которого вы запускаете apache (обычно `www-data`), не имеет разрешений на использование` at`, и вы не можете его настроить, вы можете попробовать использовать `<? php exec ('sudo sh -c "echo \" ...

Ответ #3

Ответ на вопрос: Асинхронная оболочка exec в PHP

Всем пользователям Windows: я нашел хороший 9X_async способ запустить асинхронный PHP-скрипт 9X_php.ini (на самом деле он работает почти со всем).

Он 9X_asynchronously основан на командах popen() и pclose(). И 9X_shell-command хорошо работает как в Windows, так и в Unix.

function execInBackground($cmd) {
    if (substr(php_uname(), 0, 7) == "Windows"){
        pclose(popen("start /B ". $cmd, "r")); 
    }
    else {
        exec($cmd . " > /dev/null &");  
    }
} 

Исходный 9X_shell код от: http://php.net/manual/en/function.exec.php#86329

39
1

  • @davidvalentino Правильно, и ничего страшного! Если вы хотите выполнить скрипт PHP / Pyhton / NodeJS, вам нужно фактически вызвать исполняемый файл и передать ему свой скрипт. Например: вы не доба ...

Ответ #4

Ответ на вопрос: Асинхронная оболочка exec в PHP

В Linux вы можете сделать следующее:

$cmd = 'nohup nice -n 10 php -f php/file.php > log/file.log & printf "%u" $!';
$pid = shell_exec($cmd);

Это 9X_php-frameworks выполнит команду в командной строке, а затем 9X_async просто вернет PID, который вы можете проверить 9X_shell-command на > 0, чтобы убедиться, что он работает.

Этот 9X_php-frameworks вопрос похож на: Does PHP have threading?

23
2

  • Что значит "% u" $! делать именно?<p><span clas ...

Ответ #5

Ответ на вопрос: Асинхронная оболочка exec в PHP

php-execute-a-background-process есть несколько хороших предложений. Думаю, у 9X_php-fpm меня неплохой, но я пристрастен :)

13
0

Ответ #6

Ответ на вопрос: Асинхронная оболочка exec в PHP

В Linux вы можете запустить процесс в новом 9X_php-fpm независимом потоке, добавив амперсанд в 9X_php5 конце команды

mycommand -someparam somevalue &

В Windows вы можете использовать 9X_asynchronous команду DOS "запустить"

start mycommand -someparam somevalue

6
2

  • В Linux родительский элемент может блокироваться до тех пор, п ...

Ответ #7

Ответ на вопрос: Асинхронная оболочка exec в PHP

правильный (!) способ сделать это -

  1. вилка()
  2. setsid()
  3. execve()

fork 9X_php-frameworks разветвляется, setsid сообщает текущему 9X_php процессу стать ведущим (без родителя), execve 9X_shellscript сообщает, что вызывающий процесс должен 9X_shell быть заменен вызываемым. чтобы родитель 9X_php.ini мог уйти, не затрагивая ребенка.

 $pid=pcntl_fork();
 if($pid==0)
 {
   posix_setsid();
   pcntl_exec($cmd,$args,$_ENV);
   // child becomes the standalone detached process
 }

 // parent's stuff
 exit();

6
1

  • Проблема с pcntl_fork() заключается в том, что вы не должны использовать его пр ...

Ответ #8

Ответ на вопрос: Асинхронная оболочка exec в PHP

Я использовал это ...

/** 
 * Asynchronously execute/include a PHP file. Does not record the output of the file anywhere.  
 * Relies on the PHP_PATH config constant.
 *
 * @param string $filename  file to execute
 * @param string $options   (optional) arguments to pass to file via the command line
 */ 
function asyncInclude($filename, $options = '') {
    exec(PHP_PATH . " -f {$filename} {$options} >> /dev/null &");
}

(где PHP_PATH - это константа, определенная 9X_asynchronous-processing как define('PHP_PATH', '/opt/bin/php5') или аналогичная)

Он передает аргументы 9X_php через командную строку. Чтобы прочитать 9X_php-fpm их на PHP, см. argv.

6
0

Ответ #9

Ответ на вопрос: Асинхронная оболочка exec в PHP

Я также нашел Symfony Process Component полезным для этого.

use Symfony\Component\Process\Process;

$process = new Process('ls -lsa');
// ... run process in background
$process->start();

// ... do other things

// ... if you need to wait
$process->wait();

// ... do things after the process has finished

Посмотрите, как 9X_shell-scripting это работает, в GitHub repo.

5
1

  • Предупреждение: если вы не дождетесь, процесс будет остановлен, когда з ...

Ответ #10

Ответ на вопрос: Асинхронная оболочка exec в PHP

Единственный способ, который действительно 9X_shellscript работал у меня, был:

shell_exec('./myscript.php | at now & disown')

4
1

  • 'disown' встроен в Bash и не работает с shell_exec() таким образом. Я попробовал `shell_exec (" / usr / local / sbin / command.sh 2> & 1> / dev / null | сейчас и отклонить ")` и все, что ...

Ответ #11

Ответ на вопрос: Асинхронная оболочка exec в PHP

Вы также можете запустить скрипт PHP как 9X_shell-command демон или cronjob: #!/usr/bin/php -q

2
0

Ответ #12

Ответ на вопрос: Асинхронная оболочка exec в PHP

Используйте именованный FIFO.

#!/bin/sh
mkfifo trigger
while true; do
    read < trigger
    long_running_task
done

Затем, когда 9X_shellscript вы захотите запустить длительную задачу, просто 9X_shell-command напишите новую строку (неблокирующую в файл 9X_shell-command триггера.

Если введенные вами данные меньше 9X_php PIPE_BUF и представляют собой единственную операцию 9X_php.ini write(), вы можете записывать аргументы в файл 9X_asynchronous-processing FIFO и отображать их как $REPLY в скрипте.

1
0

Ответ #13

Ответ на вопрос: Асинхронная оболочка exec в PHP

без очереди использования вы можете использовать 9X_php-frameworks proc_open() следующим образом:

    $descriptorspec = array(
        0 => array("pipe", "r"),
        1 => array("pipe", "w"),
        2 => array("pipe", "w")    //here curaengine log all the info into stderror
    );
    $command = 'ping stackoverflow.com';
    $process = proc_open($command, $descriptorspec, $pipes);

1
0