|
ru.perl- RU.PERL ---------------------------------------------------------------------- From : Gregory L. Semyonov 2:5020/400 23 Jan 2006 19:57:25 To : Artem Chuprina Subject : Re: Производительность скриптов -------------------------------------------------------------------------------- > Первое правило в такой ситуации - не запускать скрипт на каждый чих. > Если snmptrapd иначе не умеет, его и чинить. Так и есть, snmptrapd запускает обработчик не для всех подряд трапов, а только для тех, которые нужны (имеют правильный OID). >Если тем не менее уперлось > именно его в непочиненном состоянии - запускать скомпилированный сишный > враппер, который будет передавать данные постоянно запущенному скрипту. Последовал мудрому совету и взялся за написание сишного враппера. Планирую написать враппер, который будет отправлять данные через named pipe демону на Perl. Возможные ситуации: 1) Враппер пытается писАть в pipe в то время, когда его никто не читает (например демон не запущен). В этом случае происходит блокировка в вызове open. Выход - использовать флаг O_NDELAY, тогда open вернет -1. 2) Демон читает данные, но по тем или иным причинам данные не кончаются (http://www.unix.org.ua/orelly/perl/cookbook/ch16_12.htm). Выход - при помощи alarm() лимитировать время, которое демон должен тратить на чтение. Hачал эксперименты, раньше никогда не приходилось работать с named pipes. Вот код, с которым несколько вопросов: #!/usr/bin/perl -w use Fcntl; $pipe_is_opened = 0; # Move on to the next queued process $SIG{ALRM} = sub { close(FIFO) if $pipe_is_opened; $pipe_is_opened = 0; }; # Main program cycle while (1) { # Set timer to off alarm(0); # Open the pipe if( not $pipe_is_opened ){ # Here we're blocked and wait for writers sysopen (FIFO, "testpipe", O_RDONLY) || die "Can't open the pipe : $!\n"; $pipe_is_opened = 1; } # print "$!\n"; # Here the 'Illegal seek' appears # Writer has appeared, we have 1 second to read its data alarm(1); $str = ""; do { $ret_val = read FIFO, $buff, 512; last if !defined $ret_val; # The error occured $str .= $buff; } while ( $ret_val ); # Turn off the timer alarm(0); # Did we read something? if( $str ne "" && defined $ret_val ){ chomp $str; print "'".$str."'\n"; } # Prepare next iteration $ret_val = undef if defined $ret_val; close(FIFO); $pipe_is_opened = 0; } Основной вопрос - это наличие close(FIFO) в главном цикле. Если закомментировать close и следующую за ним строку, то получается следующее: запускаем скрипт, происходит блокировка в open до тех пор, пока кто-нибудь не отправит что-нибудь в pipe; далее успешно получаем данные, печатаем их на экран и идем на след. итерацию, но уже ничего не можем получить, read постоянно возвращает 0, несмотря на то, что враппер пишет и считает, что на другом конце кто-то есть (ф-ция open враппера возвращает не отрицательное значение). Вопрос 1: насколько ресурсоемка операция open, много ли времени тратится на нее? Вопрос 2: если использовать close, то возможен вариант, когда враппер начнет попытку записи в pipe как раз в тот момент, когда демон уже сделал close, но еще не успел сделать open в новой итерации. Делать во враппере несколько попыток записи? Вопрос3: не пойму откуда берется 'Illegal seek' в $! сразу после open. Любые замечания, буду признателен. Удачи, Gregory L. Semyonov --- ifmail v.2.15dev5.3 * Origin: Vostoktelecom (2:5020/400) Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор
Архивное /ru.perl/5411190055cd.html, оценка из 5, голосов 10
|