URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 5711
[ Назад ]

Исходное сообщение
"fork удаления зомби - и удаление pid из хеша"

Отправлено Dimitry , 14-Сен-06 05:04 
Создаются процессы через 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});

    }
}


Содержание

Сообщения в этом обсуждении
"fork удаления зомби - и удаление pid из хеша"
Отправлено wwwdev , 15-Сен-06 02:29 

>Проблема в том что если идёт 30-40 запросов в секунду то процессы
>то без проблем создаются и зомби отмирают, но из хеш массива
>не удаляются.
>
>Непойму что за проблема может быть.. может ктото встречался с таким?
>Повторюсь, при 10-20 запросах в секунду всё ок.
>

Скорее всего, потому что одновременно завершается несколько потомков, а ты получаешь pid последнего. На этом сайте есть faq по программированию в юникс, там этот вопрос разбирается.


"fork удаления зомби - и удаление pid из хеша"
Отправлено Dimitry , 21-Сен-06 04:07 
>
>>Проблема в том что если идёт 30-40 запросов в секунду то процессы
>>то без проблем создаются и зомби отмирают, но из хеш массива
>>не удаляются.
>>
>>Непойму что за проблема может быть.. может ктото встречался с таким?
>>Повторюсь, при 10-20 запросах в секунду всё ок.
>>
>
>Скорее всего, потому что одновременно завершается несколько потомков, а ты получаешь pid
>последнего. На этом сайте есть faq по программированию в юникс, там
>этот вопрос разбирается.


Много всего уже перечитал, но до логического решения этой проблемы чтото немогу дойти )
Если посылается только один сигнал то всёравно поидее wait должен перебирать все процессы которые зомбировались ) Или не так? Может на столько запросов нужно несколько процессов которые обрабатывают эти запросы - чтобы сигналы успивали!?

У кого побольше опыту подскажите плиз )


"fork удаления зомби - и удаление pid из хеша"
Отправлено Retif , 26-Сен-06 10:08 
>>
>>>Проблема в том что если идёт 30-40 запросов в секунду то процессы
>>>то без проблем создаются и зомби отмирают, но из хеш массива
>>>не удаляются.
>>>
>>>Непойму что за проблема может быть.. может ктото встречался с таким?
>>>Повторюсь, при 10-20 запросах в секунду всё ок.
>>>
>>
>>Скорее всего, потому что одновременно завершается несколько потомков, а ты получаешь pid
>>последнего. На этом сайте есть faq по программированию в юникс, там
>>этот вопрос разбирается.
>
>
>Много всего уже перечитал, но до логического решения этой проблемы чтото немогу
>дойти )
>Если посылается только один сигнал то всёравно поидее wait должен перебирать все
>процессы которые зомбировались ) Или не так? Может на столько запросов
>нужно несколько процессов которые обрабатывают эти запросы - чтобы сигналы успивали!?
>
>
>У кого побольше опыту подскажите плиз )

Для начала не советовал бы я вам в обработчике сигнала что-либо удалять. Максимум чего советую - это установку какого-нить флага удаления, а затем при возвращении в основной код производить чистку по этому флагу.

При получении сигнала выполнение кода прервется - и включится обработчик. Причем прерваться выполнение скрипта может в любом месте. Тоесть если уже запущен обработчик и вы получаете еще один SIGCHD то прервется первый обработчик для выполнения второго.Потому обработчик должен быть как можно легче и как можно меньше производить операций в памяти.


"fork удаления зомби - и удаление pid из хеша"
Отправлено Dimitry , 27-Сен-06 00:30 
Установить флаг удаления, это как? пометить процесс для удаления из кеша?
А как же 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});

    }
}


"fork удаления зомби - и удаление pid из хеша"
Отправлено Retif , 04-Окт-06 16:21 
>Установить флаг удаления, это как? пометить процесс для удаления из кеша?
>А как же 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;
}


У вас префорк - или форк по событию?