люди, есть скрипт,там цикл, в конце цикла скрипт вызывает функцию, та функция работает с сокетами и я вынес её в отдельный файл а в основном скрипте прописсал include(файл.php), нужно поставить таймаут как то на функцию целиком эту, и чтобы основной скрипт продолжал работать если функция прервалась по таймауту т.е. цикл продолжал бы выполняться, а если написсать set_time_limit(xx); в файле с функцией, то весь скрипт перестаёт работать, а нне только функция. вопросик, как прерывать функцию по условию что время её работы истекло, и продолжать выполнение php?
начал делать с помощью proc_open: Code: <?php set_time_limit(0); for($t=0;$t<100000;$t++) //цикл { $descriptorspec = array( 0 => array("pipe", "r"), // stdin это канал, из которого потомок будет читать 1 => array("pipe", "w"), // stdout это канал, в который потомок будет записывать 2 => array("file", "/tmp/error-output.txt", "a"), // stderr это файл для записи ); $process = proc_open("php", $descriptorspec, $pipes); if (is_resource($process)) { // $pipes выглядит теперь примерно так: // 0 => записываемый дескриптор, соединённый с дочерним stdin // 1 => читаемый дескриптор, соединённый с дочерним stdout // Любой вывод ошибки будет присоединён к /tmp/error-output.txt fwrite($pipes[0], func_needed_timeout($zz)); fclose($pipes[0]); while(!feof($pipes[1])) { echo fgets($pipes[1], 1024); } fclose($pipes[1]); // Важно, чтобы вы закрыли любые каналы до вызова // proc_close, чтобы исключить тупиковую блокировку $return_value = proc_close($process); echo "command returned $return_value\n"; } } function function_needed_timeout($zz) { set_time_limit(10); //здесь дописать код ункции нуждающаяся в прерывании по таймауту } ?> Думал set_time_limit если установить на родительский и дочерний процессы как в примере, всё будет работать, а нет, всё равно прерывается работа всего скрипта. Need help, как принудительно прерывать функцию под названием function_needed_timeout($zz) через заданный промежток времени?
В данном случае таймаут выставляй не с помощью set_time_limit(), а контроллируй время выполнения скрипта(`потока`) главным скриптом.
По сабжу: Таймаут на функцию - значит таймаут на соединение сокета. Функция fsockopen принимает пятый параметр timeout, по истечении которого хост считается мертвым. Таймаут на скрипт - это set_time_limit, определующий максимально допустимое время выполнения скрипта. Для неограниченного выполнения - set_time_limit(0). Функция не работает с Safe Mode. Так же не забывает про то, что у Apache есть свой таймаут и подвисшие процессы он убивает самостоятельно. Так что если хотим работы скрипта "пока не исполнится" - запускаем его через exec/system/popen и т.п.
А вот так я запускаю скрипты в фоновом режиме: PHP: if (file_exists('is_running.txt')) { writeFile(time() . '>BStart' . EOL, 'is_running.txt', 'a'); ... Тут идем сам скрипт unlink('is_running.txt'); exit; } if (isset($_GET['start'])) { writeFile(time() . '>SStart' . EOL, 'is_running.txt', 'w'); $fp = popen('php -f ' . __FILE__ . ' &', 'r'); pclose($fp); echo 'Script started!'; } Для тех, кому интерестно, что же все-таки за функция writeFile: PHP: function writeFile($data, $file, $type = 'a') { $fp = fopen($file, $type); flock($fp, 2); fwrite($fp, $data); flock($fp, 3); fclose($fp); }
Это по теории так, а на практике я имею такую ситуацию, что такой вот код являющийся частью функции: PHP: $fp=fsockopen($HostName, $HostPort, $errno, $errstr, 30); if (!$fp) //Если соединение прошло неуспешно, выводим сообщение об ошибке ставшей причиной проблемы. { echo "$errstr ($errno)<br />\n"; } else //Если соединение прошло успешно, то формируем пакет запрса к серверу. { $out = "GET .......\r\n"; ................ stream_set_timeout($fp, 30); //Выставляем таймау на операции с сервером. Если в течение заданного отрезка времени не происходит никакого //обмена данными, то считаем чо соединение подвисло и обрываем его. fputs($fp, $out); //Передаем ранее сформированный пакт данных серверу. //получаем ответ сервера в переменную $Page $Page=""; while (!feof($fp)) { $Page.=fgets($fp); } так вот, такой вод код, очень часто подвисает на неограниченное время, и только поэтому я стартанул эту темку.) пасибки большое, что пишите свои мысли по этому поводу, пока ещё не сделал что нужно, учусь типа.)
Это может произойти, если сокет все-таки открылся, но очень медленный. И запрос идет туда с очень мелкой скоростью - таймаут сокета тут не поможет(разве что очень маленький). Сталкивался с такой ситуацией.
PHP: stream_set_timeout($fp, 30); Не работал с этой функций, но мне кажется что она выставляет таймаут на каждую операцию, а не на все. Соответственно подвиснет на ограниченное, но оч большое время про плохом коннекте.