Отмена выполнения функции по лимиту времени.

  • Автор темы sanya07
  • Дата начала

sanya07

Guest
Отмена выполнения функции по лимиту времени.

Linux+Apache+PHP.
Мультипортовая карта, подключены 4 текстовых терминала по прот. vt100.
Контроль передачи программный с XON/XOF.
Данные на терминалы отправляются средствами Apache+PHP,
посредством :
PHP:
$com=fopen ("/dev/ttyS0","w"); 
fputs($com,"my file");
В случае проблемы с терминальными принтерами (бумага и т.д.), терминал не может слить на принтер и при переполнении буфера шлет Xoff на сервер.
В этом случае fputs() без ошибок, просто висит, естестественно на другие терминалы данные не идут.
Второй день пытаю поисковики - без толку.
Подскажите как средствами PHP по истечению допустим 5 сек.
прервать fputs($com,"my file") для "заклинившего" терминала продолжить выполнение скрипта для других терминалов, чтоб в конце скрипта вывести сообщение где авария.
Но как поставить на время выполнения fputs...??
 

svetasmirnova

маленький монстрик
Xoff может отловить что-нибудь, кроме программы, которая исполняет fputs()?
Идея такая. Непроверенная (!) Форкать fputs-ы и отлавливать Xoff-ы посторонним каким-нибудь процессом (родителем?). При отлове посылать SIGTERM зависшему процессу.
 

P.Anton

Новичок
Есть такая идея, но на практике не проверялась
Попробуй так:

Сделай скрипт, который отправляет данные на терминал
<?

function _OnTerminate() {
//функция остановки
//здесь можно проверить connection_status().
if (connection_status()==2) {
//Скрипт заверщился по таймауту
//Можно записать ощибку в файл и т.д.
}
}

register_shutdown_function("_OnTerminate");
ini_set ("max_execution_time",5); //Макс время работы скрипта

//main
$com=fopen ("/dev/ttyS0","w");
fputs($com,"my file");

?>

Из другого скрипта вызывай его для каждого терминала
 

sanya07

Guest
Единственный (найденный мной) способ отловить ^S Xoff -
это считывать с регистра UART данные на низком уровне с помощью асемблера или С, на что уйдет масса времени, да и опыта явно не хватит.
Очередная идея с set_time_limit - тоже не подошла, оказывается :
функция set_time_limit() и директива конфигурации max_execution_time влияют только на время выполнения самого скрипта. Любое время, затраченное на деятельность вне выполнения скрипта, такую как системные вызовы с помощью system(), функция sleep(), запросы к БД etc. не включается при подсчёте максимального времени работы скрипта.
Поэтому при max_execution_time=30, скрипт висит часами...))
 

sanya07

Guest
К сожалению max_input_time тоже не отключает скрипт
 

Tor

Новичок
форкаться и пересылать потомку данные для отправки на терминал
потомок отправил - доложился
если за 10 сек не доложился - прибиваем его, грязно ругаемся оператору
 

sanya07

Guest
А поддерживает-ли PHP фоновый режим.
Т.е. возможно-ли из одного скрипта запустить еще два в фоновом режиме.
В одном sleep(5) в другом fputs(), по окончанию первого смотреть процесс второго и в случае если он есть тушить его ?
 

Tor

Новичок
system()
If you start a program using this function and want to leave it running in the background, you have to make sure that the output of that program is redirected to a file or some other output stream or else PHP will hang until the execution of the program ends.
 

sanya07

Guest
Автор оригинала: Tor
форкаться и пересылать потомку данные для отправки на терминал
потомок отправил - доложился
если за 10 сек не доложился - прибиваем его, грязно ругаемся оператору
Ну а как засечь эти 10 сек.
Если не тяжело - хоть структурный код пожалуйста.
 

sanya07

Guest
При вызове скрипта отправки с помощью system() или exec()
все равно подвисает основной скрипт...(((
 

sanya07

Guest
Ну вот простой тест:

Запускающий скрипт
PHP:
<?
print "BEGIN\n";
exec("/usr/bin/php /home/myname/script_child.php &")
print "END\n";
>?
Скрипт /home/myname/script_child.php:
PHP:
<?
sleep(20);
>?
В фоновом режиме основной скрипт должен вывести
BEGIN
END
и закрыть свой процесс.
Дочерний должен висеть в процессе 20 сек. и закрытся.

У меня получается:
BEGIN
... 20 сек ...
END

А может я просто чето не догоняю...))
 

md5hash

Новичок
может я чего то не догоняю но помоему тут так получается
BEGIN
... 20 сек ...
END
на код посмотри внимательно. и сравни с этим как думаешь что будет?

PHP:
exec("/usr/bin/php /home/myname/script_child.php &")
print "BEGIN\n";
print "END\n";
Вот это будет:
... 20 сек ...
BEGIN
END
 

Tor

Новичок
видно, кто-то не понимает с первого раза
мне не тяжело, повторю

system()
If you start a program using this function and want to leave it running in the background, you have to make sure that the output of that program is redirected to a file or some other output stream or else PHP will hang until the execution of the program ends.
 

sanya07

Guest
Автор оригинала: Tor
видно, кто-то не понимает с первого раза
мне не тяжело, повторю
Да нет все понял с первого раза, просто запутался в синтаксисе перенаправлений, короче заработало так:
PHP:
exec("/usr/bin/php /home/myname/script_child.php 1>/dev/null 2>&1 &")
Хотел-бы посоветоватся насчет остального, думаю сделать так (но возможно кто-то оптимизирует)
Основной скрипт:
PHP:
//формирую данные для передачи на терминал
.....
//сливаю данные в файл (на диск)
.....
//запускаю дочерний скрипт с параметрами куда отправлять
$term="/dev/ttyS0";
exec("/usr/bin/php /home/myname/script_child.php $term 1>/dev/null 2>&1 &")
//жду
sleep(5);
//если файл getmypid существует дочерний скрипт - висит
//читаю его pid и грохаю
system("kill -9 PID");
//отмечаю что данные на этот терминал не отправлены и в цикле следующий терминал.
Дочерний скрипт script_child.php
PHP:
//создаю файл getmypid и записываю pid текущего процесса
posix_getpid();
//читаю файл с данными для передачи
...
//пытаюсь отправить данные
....
//удаляю файл getmypid (если на отправке не повис, pid мне уже не нужен)
 
Сверху