короче у меня есть прога, которая логфайл пробрасывает в сокет на отфорканные сервера, т.е. к ним пррисоедяняются клиенты и работают.
Проблема в чем, если клиенты присоединились и работают постоянно,
то никаких зомби нет. но ежели начать постоянно присоединяться
и отсоединяться после получения например одной строчки - то рано
или поздно отфорканные серверы становятся зомбями и висят в
процессах с индексом defunct
что я делаю не так?
#!/usr/bin/perl -w
use lib '/u/vilfred/bwcsII-unix-0.8/weather/File-Tail-0.99.3/blib/lib/';
use File::Tail;
use IO::Socket;
use Symbol;
use POSIX;
$l = '/u/vilfred/bwcsII-unix-0.8/weather/log.txt';
#логфайл, который надо пробросить в сокет
$PORT=15012;
номер порта сокета
$server = IO::Socket::INET->new( Proto => 'tcp',
LocalPort => $PORT, Listen => SOMAXCONN,
Type => SOCK_STREAM, Reuse => 1) or die " making socket: $@";
#поднимаем исходно сервер
$PREFORK =5;
#число предварительно отфорканных серверов
$MAX_CLIENTS_PER_CHILD = 5;
#число клиентов, которые могут подсоединяться к каждому из серверов
%children=();
#хеш детей(номер дитяти => его номер процесса)
$children=0;
#колво детей
make_new_child() for(1 .. $PREFORK);
#цикл поддержания постоянного кол-ва
$SIG{CHLD}=\&REAPER;
#перехватчик сигнала CHILD
$SIG{INT}=\&HUNTSMAN;
#перехватчик killint
while(1){
sleep;
for($i=$children; $i<$PREFORK; $i++){make_new_child()}
}
#цикл поддержания постоянного колва серверов, если клиент
#отсоединился и в месте с ним умер и сервер, нужен чтобы возродить
#новый сервер
sub tail_socket{
#смотрим в в хвост файла по аналогии с командой tail -f
return $fi = File::Tail->new(
name => $l,
maxinterval => 0.1,
adjustafter => 1000000000,
interval => 4,
tail => 0)
}
sub make_new_child{
#делаем дитенка сервер
my $pid;
my $sigset;
$sigset=POSIX::SigSet->new(SIGINT);
sigprocmask(SIG_BLOCK, $sigset) or die "can't block SIGINT for fork: $!\n";
die "fork: $!" unless defined($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($i=0; $i<$MAX_CLIENTS_PER_CHILD; $i++){
$client = $server->accept() or last;
#поключаем клиента или выходим
&tail_socket();
#тайлим сокет
while(1){
#пока есть подключение - данные из хвоста файла запихиваем клиенту
print $client $_ while($_=$fi->read);
}
} exit;
}
}
sub HUNTSMAN{
local($SIG{CHLD})='IGNORE';
kill 'INT' => keys %children;
exit;
}
sub REAPER{
$SIG{CHLD}=\&REAPER;
my $pid = wait;
$children--;
delete $children{$pid};
}
Короче, что я делаю не так, чтобы избежать зомбей при большом
колве подключений и отключений?? Оно не может убить зомби почемуто вобщем.
Ответ на:
комментарий
от Begemoth

Ответ на:
комментарий
от vilfred
Ответ на:
комментарий
от vilfred
Ответ на:
комментарий
от vilfred

Ответ на:
комментарий
от mky

Ответ на:
комментарий
от anonymous



Ответ на:
комментарий
от vilfred

Ответ на:
комментарий
от mky

Ответ на:
комментарий
от PoMbl4

Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.
Похожие темы
- Форум сегфолт в perl gtk2, которого раньше не было (2014)
- Форум [perl] проброс проги в сокет (2008)
- Форум Почему не работает скрипт? (2013)
- Форум Cinnamon плодит зомби после запуска Wine (2015)
- Форум зомби (2008)
- Форум Воскрешение зомби (2012)
- Форум Pidgin - зомби (2013)
- Форум Тукс - зомби (2012)
- Форум Прибить «зомби» (2005)
- Форум процесс-зомби (2002)