Intereting Posts
Какой RSS-парсер следует использовать в PHP? объявление атрибута класса проверьте руководство, соответствующее версии вашего сервера MySQL, для правильного синтаксиса для использования рядом с '' в строке 1 Symfony 1.4: PHP Неустранимая ошибка: допустимый размер памяти 33554432 байт исчерпан Предупреждение Mysqli_Query: mysqli_query () ожидает, что параметр 1 будет mysqli Ошибка синтаксиса T_CONSTANT_ENCAPSED_STRING Laravel 4 Отношения между мужчинами и женщинами Найти внутренние массивы в вложенных массивах ловить все ошибки и перенаправлять на страницу с помощью php слияние двух массивов и сохранение повторяющихся значений Библиотека PHP, которая генерирует текст ASCII Art локализовать порядковые номера Как стимулировать запрос cURL на запрос с использованием почтового менеджера JQuery / Ajax Обновить без перезагрузки или загрузки страницы? Как не удалось выполнить запрос HTTP! HTTP / 1.1 463?

PHP устанавливает тайм-аут для скрипта с системным вызовом, set_time_limit не работает

У меня есть PHP-скрипт командной строки, который запускает запрос wget, используя каждый член массива с foreach. Этот запрос wget иногда занимает много времени, поэтому я хочу установить тайм-аут для убийства скрипта, если он, например, занимает 15 секунд. У меня отключен Safemode PHP и в начале скрипта вызывается set_time_limit (15), однако он продолжается бесконечно. Обновление: спасибо Дор за это, потому что set_time_limit () не поддерживает вызовы system ().

Поэтому я пытался найти другие способы убить скрипт после 15 секунд исполнения. Однако я не уверен, можно ли проверить время запуска скрипта, когда оно находится в середине запроса wget в то же время (цикл while не работает). Может быть, разветвить процесс с помощью таймера и установить его, чтобы убить родителя через определенное количество времени?

Спасибо за любые советы!

Обновление: Ниже мой соответствующий код. $ url передается из командной строки и представляет собой массив из нескольких URL-адресов (извините за то, что вы не опубликовали это изначально):

foreach( $url as $key => $value){ $wget = "wget -r -H -nd -l 999 $value"; system($wget); } 

Вы можете использовать комбинацию «–timeout» и time (). Начните с выяснения, сколько времени у вас общее, и опустите –timeout по мере запуска вашего скрипта.

Например:

 $endtime = time()+15; foreach( $url as $key => $value){ $timeleft = $endtime - time(); if($timeleft > 0) { $wget = "wget -t 1 --timeout $timeleft $otherwgetflags $value"; print "running $wget<br>"; system($wget); } else { print("timed out!"); exit(0); } } 

Примечание: если вы не используете -t, wget будет пытаться выполнить 20 раз, каждый из которых – время ожидания.

Вот пример кода с использованием proc_open / proc_terminate (предложение @ Josh):

 $descriptorspec = array( 0 => array("pipe", "r"), 1 => array("pipe", "w"), 2 => array("pipe", "w") ); $pipes = array(); $endtime = time()+15; foreach( $url as $key => $value){ $wget = "wget $otherwgetflags $value"; print "running $wget\n"; $process = proc_open($wget, $descriptorspec, $pipes); if (is_resource($process)) { do { $timeleft = $endtime - time(); $read = array($pipes[1]); stream_select($read, $write = NULL, $exeptions = NULL, $timeleft, NULL); if(!empty($read)) { $stdout = fread($pipes[1], 8192); print("wget said--$stdout--\n"); } } while(!feof($pipes[1]) && $timeleft > 0); if($timeleft <= 0) { print("timed out\n"); proc_terminate($process); exit(0); } } else { print("proc_open failed\n"); } } 

Попробуйте использовать аргумент --timeout wget --timeout в дополнение к set_time_limit() .

Помните, что set_time_limit(15) перезапускает счетчик тайм-аута с нуля, поэтому не вызывайте его внутри цикла (для вашей цели)

от man wget :

–timeout = секунды

Установите тайм-аут сети на секунды. Это эквивалентно заданию –dns-timeout, -connect-timeout и -read-timeout, одновременно.

При взаимодействии с сетью Wget может проверять таймаут и прерывать операцию, если она занимает слишком много времени. Это предотвращает аномалии, такие как висящие чтения и бесконечные соединения. Единственный тайм-аут, включенный по умолчанию, – это 900-секундный тайм-аут чтения. Установка тайм-аута на 0 полностью отключает его. Если вы не знаете, что делаете, лучше не изменять настройки тайм-аута по умолчанию.

Все параметры, зависящие от тайм-аута, принимают десятичные значения, а также значения подсегмента. Например, 0,1 секунды является законным (хотя и неразумным) выбором таймаута. Субсекундные тайм-ауты полезны для проверки времени ответа сервера или проверки задержки сети.

EDIT: ОК. Я вижу, что ты сейчас делаешь. Вероятно, вам следует использовать proc_open вместо system и использовать функцию time() для проверки времени, вызывая proc_terminate, если wget tskes слишком длинный.

Вы можете направлять вывод программы wget в файл, который затем немедленно возвращается.
Также см:

Примечание. Функция set_time_limit () и директива конфигурации max_execution_time влияют только на время выполнения самого скрипта. Любое время, затрачиваемое на активность, которое происходит вне выполнения сценария, например системные вызовы с использованием system (), потоковые операции, запросы к базе данных и т. Д., Не включается при определении максимального времени выполнения сценария. Это не относится к Windows, где измеренное время реально.

Источник: set_time_limit () @ php.net