Тайм-аут функции в PHP

Есть ли способ отключить функцию? У меня есть 10 минут, чтобы выполнить работу. Работа включает цикл for, вот пример:

<?php
foreach($arr as $key => $value){
   some_function($key, $value); //This function does SSH and SFTP stuff
}
?>

$ arr имеет 15 элементов, а иногда some_function () может занять более 1 минуты. На самом деле однажды его повесили на 5 минут.

Есть ли способ, которым я могу тайм-аут вызова функции и перейти к следующему элементу в $ arr?

Спасибо!!

 aurora14 мая 2012 г., 18:32
некоторые вопросы: что ограничивает вас 10 минутами? не имеет значения, выполняются ли задания ssh / sftp или нет? и можете ли вы обойти это ограничение, используя какую-то очередь?
 Mo3z14 мая 2012 г., 21:13
Это скрипт crontab, который запускается каждые 10 минут. Он проверяет состояние серверов и обновляет базу данных. Если я не получаю ответ в течение 1 минуты, я устанавливаю этот медленный сервер ...

Ответы на вопрос(7)

set_time_limit, Теперь сама функция на самом деле не хочет, чтобы вы хотели, так как она принимает во внимание только время выполнения, то есть 5 секунд в реальной жизни все еще могут быть только 0,2 секундами выполнения. Но причина просмотра ссылки - комментарии. Есть несколько решений, которые пользователи опубликовали.

time(), В конце каждой итерации проверьте, является ли текущийtime() больше чем на 60 секунд Если так,break, Например:

<?php
$startTime=time();
foreach($arr as $key => $value){
    some_function($key, $value); //This function does SSH and SFTP stuff
    if (time()-$startTime>60) break; //change 60 to the max time, in seconds.
}
?>
 Mo3z14 мая 2012 г., 18:50
Спасибо Дэвид за ваш ответ. Мне не нужно прерывать цикл for, мне нужно прерывать функцию some_, если это занимает больше минуты.
Решение Вопроса

ие обработки не будет продолжаться, пока текущая функция не будет завершена. Однако, если функция содержит цикл, вы можете добавить его в свой собственный код, чтобы прерывать цикл после выполнения определенного условия.

Что-то вроде этого:

foreach ($array as $value) {
  perform_task($value);
}

function perform_task($value) {
  $start_time = time();

  while(true) {
    if ((time() - $start_time) > 300) {
      return false; // timeout, function took longer than 300 seconds
    }
    // Other processing
  }
}

Другой пример, где прерывание обработки НЕ возможно:

foreach ($array as $value) {
  perform_task($value);
}

function perform_task($value) {
    // preg_replace is a blocking function
    // There's no way to break out of it after a certain amount of time.
    return preg_replace('/pattern/', 'replace', $value);
}
 05 июл. 2014 г., 02:43
та же проблема здесь, та же техника.
 Mo3z14 мая 2012 г., 21:11
Путь по маршруту: создание нового сценария example.php и вызов этого сценария в some_function и определение set_time_limit ... логика some_function будет выполнена в example.php ..
 Mo3z14 мая 2012 г., 18:49
Спасибо, Майк, но у меня есть some_function, или execute_task - это основная функция, и я пытаюсь избежать изменения основного метода.

ОС для форкирования другого процесса.

Единственный способ, которым я знаю, как это сделать, - выполнить команду exec, чтобы отключить еще один полный процесс. Поместите нужные вам вещи в отдельный скрипт, вызовите exec для скрипта и сразу же поспите 10 минут. Если через 10 минут процесс все еще работает, убейте его. (вы должны иметь его PID, заставив команду запустить новый php-код в фоновом режиме, получив его из командной строки и вернув его из команды exec).

 15 февр. 2018 г., 03:56
Не весь PHP не является многопоточным

используя 'curl'. Curl - из PHP - в основном используется для HTTP / FTP, но он поддерживает гораздо больше протоколов, включая ssh / sftp. Я никогда не делал что-то связанное с ssh / sftp с помощью curl, поэтому я не могу дать никаких дополнительных советов, но вы должны быть в состоянии найти дополнительную информацию здесь о stackoverflow или где-то еще.

Существует опция & quot; CURLOPT_TIMEOUT & quot; Вы можете использовать его для настройки тайм-аута для вашего запроса (также имеется опция «CURLOPT_CONNECTTIMEOUT»). Вы даже можете указать время ожидания в миллисекундах (CURLOPT_TIMEOUT_MS / CURLOPT_CONNECTTIMEOUT_MS).

В любом случае: для cronjob я бы рекомендовал использовать дополнительный & quot; файл блокировки & quot; Ваш сценарий пишет, когда он запущен, и удаляет, когда он завершается. Вы можете проверить этот файл блокировки в вашем скрипте, так что если cron запускает ваш скриптbefore последний запуск завершен, вы можете просто выйти из сценария без каких-либо дополнительных действий. Это гарантирует, что ваш скрипт не будет выполняться несколько раз параллельно.

Вы можете найти больше информации о параметрах CURL и самом CURL в документации PHP:

http://www.php.net/manual/en/function.curl-setopt.php http://www.php.net/manual/en/book.curl.php

Вы должны убедиться, что ваш установленный libcurl и / или curl для php поддерживает SSH / SFTP, хотя:

SFTP from PHP - undefined constant CURLOPT_PROTOCOLS and CURLPROTO_SFTP? SFTP from within PHP

и т.п.

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

которая будет запускать сигнал SIGALRM по таймауту. Например:

// 10 minutes
pcntl_alarm( 600 );
pcntl_signal( 'SIGALRM', function() { print( "I am done!\n" ); exit( 0 ); } );

Пожалуйста, смотрите здесь руководство по PHP для получения дополнительной информации об этом:http://php.net/manual/en/function.pcntl-alarm.php

 26 янв. 2017 г., 16:26
Вот полная реализация:gist.github.com/avalanche123/3085581
 09 апр. 2018 г., 22:21
Вроде работает только сsleep() функция.curl_exec() а такжеfile_get_contents() К сожалению, время ожидания этого решения не истекло.

кто находится в командной строке, посмотрите, как прерывается сон:

echo date("H:i:s\n");
pcntl_signal(SIGALRM ,function($signal){
echo "arghhh! i got interrupted \n";
},true);

pcntl_alarm(3);
sleep(20);
pcntl_signal_dispatch();


echo date("H:i:s\n");

pcntl_alarm(3);
sleep(20);

echo date("H:i:s\n");

pcntl_signal_dispatch();
echo "end\n";

Ваш ответ на вопрос