Дождитесь определенного времени выполнения одной строки, иначе вернитесь

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

проблема

Когда я хочу получить вывод процесса, нет ответа от конечного сервера, и скрипт будет ждать ответа до …..

Вопрос

Я хочу сказать, что ждать ответа в течение 20 секунд, и если вы не получили никакого ответа. возврат из функции. Это важно, что я не хочу останавливать выполнение скрипта, а просто возвращаюсь из функции.
Должен ли я использовать многопоточные библиотеки в качестве POSIX?

Есть ли способ реализовать эту идею?
Любая идея будет оценена. заранее спасибо

Пример кода

<?PHP
set_time_limit(0);

.....

public function test()
{
foreach ($this->commands as $cmd)
{
fwrite($pipes[0], "$cmd \n");

//Sometimes PHP stuck on the following line
//Wait for almost 20 sec if respond did not came return
$read = fread($pipes[1], 2096) . "\n";
}
}

1

Решение

Вы не сказали, на какой ОС это работает, хотя упоминали POSIX. Ни какой SAPI. В совокупности они оказывают большое влияние на ваши варианты.

Кроме того, вы не сказали, что это за процесс, который вы начали, и как его следует обрабатывать, когда он истекает. Закрытие потоков stdio может привести к сбою процесса. Если вы хотите отправить сигнал, вам нужно знать pid (IIRC недоступен из proc_open ()).

Непосредственная проблема, с которой вы столкнулись, заключается в том, что поток по умолчанию блокирует чтение, поэтому простое его установление без блокировки позволяет преодолеть первое препятствие:

set_stream_blocking($pipes[1],false);
...

fwrite($pipes[0], "$cmd \n");
$ttl=time()+20;
while(''==$read && time()<$ttl) {
$read=fread($pipes[1],2096);
if (!$read) sleep(1);
}
if (!$read) echo " timeout";

(Кстати, это, вероятно, не будет работать на mswindows)

0

Другие решения

использование stream_set_timeout (но после fwrite, если тот же поток):

fwrite($pipes[0], "$cmd \n");
stream_set_timeout($pipes[1], 20);
$read = fread($pipes[1], 2096) . "\n";

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

$r = [$pipes[0]];
$w = $e = null;
if( stream_select($r, $w, $e, 20) !== false )
foreach($r as $s)
$read = fread($s,2096);

Надеюсь, это поможет?

0

По вопросам рекламы [email protected]