PHP proc_open открывается несколько раз
У меня есть служебная функция, используемая для выполнения программы через CLI (cmd, bash и т. Д.). Возвращает массив из 3 элементов: STDOUT
, STDERR
а также EXIT CODE
,
Пока что все работает хорошо, без проблем. На самом деле, проблема, с которой я столкнулся, на самом деле не мешает его функциональности, но я беспокоюсь о производительности.
Проблема в том, что в некоторых случаях PHP выполняет одну и ту же команду несколько раз (в моем случае - 3 раза), даже если предполагалось, что она будет делать это только один раз.
/**
* Executes a program and waits for it to finish, taking pipes into account.
* @param string $cmd Command line to execute, including any arguments.
* @param string $input Data for standard input.
* @param boolean $log Whether to log execution failures or not (defaults to true).
* @return array Array of "stdout", "stderr" and "return".
*/
public static function execute($cmd,$stdin=null,$log=true){
//static $once=true; if(!$once)die; $once=false;
$proc=proc_open($cmd, array(
0=>array('pipe','r'),
1=>array('pipe','w'),
2=>array('pipe','w') ), $pipes);
fwrite($pipes[0],$stdin); fclose($pipes[0]);
$stdout=stream_get_contents($pipes[1]); fclose($pipes[1]);
$stderr=stream_get_contents($pipes[2]); fclose($pipes[2]);
$return=proc_close($proc);
if($return!=0 && $log)
xlog('Error: Program execution returned failure.',$stdout,$stderr,$return);
return array( 'stdout'=>$stdout, 'stderr'=>$stderr, 'return'=>$return );
}
Обратите внимание на закомментированную строку (строка 9). Это было для тестирования. Я включил его, чтобы целевая программа запускалась только один раз (я думал, что мой код может как-то вызывать ту же функцию). Но даже если эта строка включена, программа все равно запускалась несколько раз.
В моем коде есть 2 места, где я выполняю одну и ту же программу (в разных случаях). Командная строка одинакова для них обоих.
Однако в одном случае программа запускается один раз, в то время как в этом случае PHP запускает программу 3 раза.
Я наблюдал и видел это поведение в Process Explorer. Я использую Windows 7 x64. Программа 32-х битная, как и PHP.
Редактировать: рассматриваемая программа разработана на заказ, и она не открывает новые процессы.
3 ответа
Ваш код для проверки его запуска только один раз выглядит некорректно.
Если у вас запущены 2 процесса php, они не будут использовать статическую переменную. Таким образом, возможно, у вас есть одновременные запросы, которые приводят к запуску более одного раза.
Во-вторых, вы должны установить $once
false в конце функции, в противном случаеdie
никогда не будет достигнут
Попробуйте добавить запись в журнал, чтобы узнать, вызывается ли функция дважды.
Создайте несколько модульных / стресс-тестов, которые просто запускают внешнее приложение. Если вы видите несколько процессов, значит в вашем приложении что-то не так, а не код php.
Это очень странно. И это очень трудно понять без полного кода.
Если вы подчеркиваете, что ваш сервер вызывает одну и ту же страницу несколько раз, я бы поспорил, что это, вероятно, связано с процессом циклического перебора ЦП. PHP не успевает установить статическую переменную в false, потому что в то же время есть другой запрос к этому методу. Другая возможность заключается в том, что PHP не может должным образом изолировать статическое значение, и другой запрос к этому методу может считывать различные позиции в памяти, пока PHP не синхронизирует значения.
Я знаю, что это может быть не лучшим вариантом, но это то, что я сделал. Хотя это было на Linux, но я уверен, что есть способ перенести это на Windows.
Что я сделал, так это запустил pgrep и проверил, существует ли уже команда, подобная этой, и просто ли она завершается. Как вы сказали, вы выполняете ту же команду (с точными параметрами), поэтому просто проверьте, выполняется ли уже команда, и действуйте соответственно.
Я использовал эту команду:
$pid = shell_exec('pgrep -cfx "/* My command */"');
if ($pid > 1) return -1;