|
|
ru.perl- RU.PERL ---------------------------------------------------------------------- From : vilfred 2:5020/400 17 Jul 2003 19:16:08 To : Edik Ryzhov Subject : Re: Многозадачность в эхотаге -------------------------------------------------------------------------------- Привет!! ER> Стоит задача написать что-то вpоде демона, по таймеpy/pасписанию запyскающемy ER> опpеделенные пpогpаммки и обpабатывающемy их коды возвpата. Посколькy ER> пpогpаммки могyт выполняться довольно долго, хочется pеализовать сабж, чтобы ER> шедyлеp/демон не висел в ожидании окончания одной пpогpаммы, а запyскал сpазy ER> несколько. Сижy yже 8 часов - кypю perlfunc,perlipc,perlthrtut и ничего не ER> полyчается =( Возьмите книжку "Perl Библиотека программиста"... вообще, имхо, достаточно этой книги и perldoc perlipc Вам надо посадить демона, который бы сам эмулировал кронтаб. По запусканию определенной проги он бы форкал процесс, который контролировал бы вывод этой проги. Потому как если с кронтабом работать, надо будет кронтабом запускать определенннеую прогу, которая бы звонила к перловому демону, а это неудобно... И еще, в перле как нигде удобно работать с отфорканными процессами, открывать дексрипторы(пайпы, каналы, трубы - кому как нравится, короче IPC) между процессами, вводить общие на 2, 3, ... n процессов переменные и так далее... эхотаг это не язык, а вообще какой-то гипермегасупер... ER> Что откpывать дочеpний пpоцесс чеpез _fork_, что чеpез ER> _open(F,"-|");_ не выходит, пpиходиться ждать STDIN. С сигналами тоже не могy ER> pазобpаться. В perlthrtut что-то написано пpо экспеpиментальный модyль Thread, ER> только его почемy-то нет в моей инсталляции, хотя в perlmodlib он описан как ER> стандаpтный. ER> Вообщем, товаpищи/господа, помогите добpым советом, кyском кода или посыланием ER> на CPAN, хотя последнее лyчше не надо, хоpошо бы только стандаpтное юзать. есть прога, которая долбится через сокет на определнный порт, в случае неудачи чайлд перезапускается, в случае удачи чайд форкается на сервер и клиент, клиент подсоединяется к той самой проге, а сервер принимет и транслирует ответы от клиентов, работающих с упомянутой прогой. Итого, один парент генерит чайлдов, которые в случае подключения сами форкают чайлдов. А все отчего, один мужик написал прогу, которая часто падает, и, к тому-же, к этой проге по сокету можно подконнектится только два раза. А надо любое число раз и пришлось писать обвязку: ========begin======= #!/usr/bin/perl -w use strict; use IO::Socket; use IO::Handle; use Socket; use Symbol; use POSIX; use Net::hostent; my $port=6001; my $host="127.0.0.1"; my $PREFORK="1"; my $MAX_CLIENTS_PER_CHILD="1"; my %children=(); my $children=0; my $f="/.2/mnt/work/control.txt"; make_new_child() for(1 .. $PREFORK); $SIG{CHLD}=\&REAPER; $SIG{INT}=\&HUNTSMAN; while(1){ sleep; for(my $i=$children; $i<$PREFORK; $i++){ make_new_child() } } sub make_new_child{ my($pid, $sigset, $kidpid, $server, $client); $sigset=POSIX::SigSet->new(SIGINT); sigprocmask(SIG_BLOCK, $sigset) or die "can't block SIGINT for fork: $!\n"; die "fork: $!" unless defined do{$pid = fork}; if($pid){ sigprocmask(SIG_UNBLOCK, $sigset) or die "can't unblock SIGINT for fork: $!\n"; $children{$pid}=1; $children++; return; } else { $SIG{INT} = 'DEFAULT'; $SIG{CHLD}='IGNORE'; sigprocmask(SIG_UNBLOCK, $sigset) or die "can't unblock SIGINT for fork: $!\n"; for(my $i=0; $i<$MAX_CLIENTS_PER_CHILD; $i++){ sleep 2; socketpair(CHILD, PARENT, AF_UNIX, SOCK_STREAM, PF_UNSPEC) or die "socketpair: $!"; #открываем двусторонний обмен данными между чайлдом и парентом CHILD->autoflush(1); PARENT->autoflush(1); #отключаем буферизацию my $handle = IO::Socket::INET->new( Proto => 'tcp', PeerAddr => $host, PeerPort => $port) or die "can't connect to port $port on $host: $!"; #поднимаем клиента print STDERR "[Connected to $host:$port]\n"; die "can't fork: $!" unless defined do{$kidpid = fork()}; if ($kidpid) { #парент, все что в этом условии работает только для парента my ($byte, $tmp); close PARENT; #так как парент, закрываем дескриптор парента while(sysread($handle, $byte, 1) eq 1){ #посимвольно читаем из сокетной проги $tmp.=$byte; do{print CHILD "$tmp\n"; #пишем в чайлд либо ok либо error $tmp='' } if $tmp eq 'ok'; do{print CHILD $tmp,"\n"; $tmp=''} if $tmp eq 'error'; } close CHILD; kill "TERM" => $kidpid; #убиваем waitpid($kidpid,0); #отслеживаем зомби } else { #тут начинается чайлд close CHILD; $server = IO::Socket::INET->new( LocalPort => 2003, Type => SOCK_STREAM, Proto => 'tcp', Reuse => 1, Listen => 10); die "making socket: $@" unless $server; #поднимаем сервер, транслирующий ответы проги, к которой #коннектятсячерез сокет, фишка в том, что #та прога отрабатывает только два подключения #а надо любое число, вот клиенты и коннектятся к серваку #любое число раз, а обмен данными происходит через #двусторонний сокет между парентом и чайлдом while($client=$server->accept()){ $client->autoflush(1); my ($line, $line1); while (defined ($line = <$client>)){ print $handle $line; #пишем в клиента, который работает с прогой команду chomp($line1=<PARENT>); #читаем из чайлда ответ print $client "$line1\n"; #пишем подконнектившемуся по сокету юзеру ответ проги } close $client; } close PARENT; } } exit; } } sub HUNTSMAN{ #отрабатываем перезапуски... local($SIG{CHLD})='IGNORE'; kill 'INT' => keys %children; exit; } sub REAPER{ #убиваем чайлда по сигналу... $SIG{CHLD}=\&REAPER; my $pid = wait; $children--; delete $children{$pid}; } =========end======== ваще когда написал - охренел, _насколько_ просто и _что_ можно перлом сделать... правда втыкал в перловые межпроцессные взаимодействия не торопять, полгода где-то... а первую прогу с IPC, которая отслеживала падение интернета через GPRS сотового телефона полтора месяца вообще писал... зато как связь в beeline падает(пинг пропадает, route прежний), гудит гудок, по которому надо нажимать на кнопку на телефоне... осталось купить телефон у которого нормальный вход есть, тогда вообще автоматически самоподдерживаемая связь будет, а пока, увы, работаем через инфракрасный порт. ER> ЗЫ. perl v5.6.1 такаяже шняга, хоят то чел, чья прога, писал ваще под дос... Дима -- TEAM [Маньяки] Отправлено через сервер Форумы@mail.ru - http://talk.mail.ru --- ifmail v.2.15dev5 * Origin: Talk.ru (2:5020/400) Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор
Архивное /ru.perl/64889f30559f.html, оценка из 5, голосов 10
|