PHP Pipe в фоновый процесс - PullRequest
       50

PHP Pipe в фоновый процесс

1 голос
/ 29 сентября 2011

Я пытаюсь использовать popen для запуска php-скрипта в фоновом режиме. Однако мне нужно передать (довольно большой) сериализованный объект.

$cmd = "php background_test.php >log/output.log &";
$fh = popen($cmd, 'w');
fwrite($fh, $data); 
fclose($fh);
//pclose($fh);

Без амперсанда этот код выполняется нормально, но родительский скрипт будет ждать, пока дочерний процесс не завершится. С амперсандом STDIN не получает данных.

Есть идеи?

Ответы [ 3 ]

1 голос
/ 29 сентября 2011

Вы можете попробовать разветвить, чтобы дочерний процесс записывал данные, и основной скрипт продолжал работать как обычно.

Примерно так

// Fork a child process
$pid = pcntl_fork();

// Unable to fork
if ($pid == -1) {
    die('error');
}

// We are the parent
elseif ($pid) {

   // do nothing 
}

// We are the child
else {

    $cmd = "php background_test.php >log/output.log";
    $fh = popen($cmd, 'w');
    fwrite($fh, $data); 
    fclose($fh);
    exit();
}


// parent will continue here
// child will exit above

Подробнее об этом здесь: https://sites.google.com/a/van-steenbeek.net/archive/php_pcntl_fork

Также проверьте функцию pcntl_waitpid () (зомби исчезнут) в документации php.

0 голосов
/ 29 сентября 2011

Заставить фоновые процессы прослушивать файл сокета. Затем откройте файл сокета из PHP и отправьте туда свои сериализованные данные. Когда ваш фоновый демон получает соединение через сокет, сделайте его форк, прочитайте данные, затем обработайте.

Тебе нужно немного почитать, но я думаю, что это лучший способ достичь этого. Под сокетом я подразумеваю файл сокета Unix, но вы также можете использовать его по сети.

http://gearman.org/ также является хорошей альтернативой, как упомянуто @ Joshua

0 голосов
/ 29 сентября 2011

Насколько я знаю, в php нет способа отправить процесс в фоновом режиме и продолжать передавать его STDIN (но, возможно, я ошибаюсь).Здесь у вас есть два варианта:

  1. Выполните рефакторинг вашего background_test.php, чтобы получить его ввод из командной строки и преобразовать вашу командную строку в php background_test.php arg1 arg2 ... >log/output.log &
  2. Если ваш ввод довольно длинный,запишите его во временный файл и затем передайте сценарий background_test.php этим файлом, как показано в следующем коде

Пример для пункта 2:

<?
$tmp_file = tempnam();
file_put_content($tmp_file, $data);
$cmd = "php background_test.php < $tmp_name > log/output.log &";
exec($cmd);
...