Создаются процессы через fork потом подают сигнал родителю и перебирая waitpid(-1,&WNOHANG) процессы удаляются из массива!Проблема в том что если идёт 30-40 запросов в секунду то процессы то без проблем создаются и зомби отмирают, но из хеш массива не удаляются.
Непойму что за проблема может быть.. может ктото встречался с таким?
Повторюсь, при 10-20 запросах в секунду всё ок.Ниже кусок обработчика.
$SIG{CHLD} = \&EndChld;
sub EndChld{
while(my $kid = waitpid(-1,&WNOHANG)){
last if $kid == -1;
print "[$$] Del PID=$kid\n";
delete($pids{$kid});}
}
>Проблема в том что если идёт 30-40 запросов в секунду то процессы
>то без проблем создаются и зомби отмирают, но из хеш массива
>не удаляются.
>
>Непойму что за проблема может быть.. может ктото встречался с таким?
>Повторюсь, при 10-20 запросах в секунду всё ок.
>Скорее всего, потому что одновременно завершается несколько потомков, а ты получаешь pid последнего. На этом сайте есть faq по программированию в юникс, там этот вопрос разбирается.
>
>>Проблема в том что если идёт 30-40 запросов в секунду то процессы
>>то без проблем создаются и зомби отмирают, но из хеш массива
>>не удаляются.
>>
>>Непойму что за проблема может быть.. может ктото встречался с таким?
>>Повторюсь, при 10-20 запросах в секунду всё ок.
>>
>
>Скорее всего, потому что одновременно завершается несколько потомков, а ты получаешь pid
>последнего. На этом сайте есть faq по программированию в юникс, там
>этот вопрос разбирается.
Много всего уже перечитал, но до логического решения этой проблемы чтото немогу дойти )
Если посылается только один сигнал то всёравно поидее wait должен перебирать все процессы которые зомбировались ) Или не так? Может на столько запросов нужно несколько процессов которые обрабатывают эти запросы - чтобы сигналы успивали!?У кого побольше опыту подскажите плиз )
>>
>>>Проблема в том что если идёт 30-40 запросов в секунду то процессы
>>>то без проблем создаются и зомби отмирают, но из хеш массива
>>>не удаляются.
>>>
>>>Непойму что за проблема может быть.. может ктото встречался с таким?
>>>Повторюсь, при 10-20 запросах в секунду всё ок.
>>>
>>
>>Скорее всего, потому что одновременно завершается несколько потомков, а ты получаешь pid
>>последнего. На этом сайте есть faq по программированию в юникс, там
>>этот вопрос разбирается.
>
>
>Много всего уже перечитал, но до логического решения этой проблемы чтото немогу
>дойти )
>Если посылается только один сигнал то всёравно поидее wait должен перебирать все
>процессы которые зомбировались ) Или не так? Может на столько запросов
>нужно несколько процессов которые обрабатывают эти запросы - чтобы сигналы успивали!?
>
>
>У кого побольше опыту подскажите плиз )Для начала не советовал бы я вам в обработчике сигнала что-либо удалять. Максимум чего советую - это установку какого-нить флага удаления, а затем при возвращении в основной код производить чистку по этому флагу.
При получении сигнала выполнение кода прервется - и включится обработчик. Причем прерваться выполнение скрипта может в любом месте. Тоесть если уже запущен обработчик и вы получаете еще один SIGCHD то прервется первый обработчик для выполнения второго.Потому обработчик должен быть как можно легче и как можно меньше производить операций в памяти.
Установить флаг удаления, это как? пометить процесс для удаления из кеша?
А как же waitpid, на него же тоже уходит время )
Что если в начале функции сново огласить обработчик сигнала, вот так.$SIG{CHLD} = \&EndChld;
sub EndChld{
$SIG{CHLD} = \&EndChld;
while(my $kid = waitpid(-1,&WNOHANG)){
last if $kid == -1;
print "[$$] Del PID=$kid\n";
delete($pids{$kid});}
}
>Установить флаг удаления, это как? пометить процесс для удаления из кеша?
>А как же waitpid, на него же тоже уходит время )
>Что если в начале функции сново огласить обработчик сигнала, вот так.
>
>$SIG{CHLD} = \&EndChld;
>sub EndChld{
>$SIG{CHLD} = \&EndChld;
> while(my $kid = waitpid(-1,&WNOHANG)){
> last if $kid ==
>-1;
> print "[$$] Del PID=$kid\n";
>
> delete($pids{$kid});
>
> }
>}IMHO вижу так
#!/usr/bin/perl -w
#...$SIG{CHLD} = \&EndChld;
#...
while(1)
{
#если поднят флаг - чистим хеш детей
if($clean_children)
{
my $child_pid;
while (($child_pid = waitpid(-1,&WNOHANG)) > 0)
{
delete $pids{$child_pid};
$total_children--;
}
$clean_children = undef;
}
# ...
}sub kill_child
{
$clean_children = 1;
$SIG{CHLD} = \&kill_child;
}
У вас префорк - или форк по событию?