Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Системное программирование > Процессы зомби


Автор: vaddsm 2.7.2007, 19:01
Прошу обратить внимание на этот лог:

Код


 PID  TT  STAT      TIME COMMAND
39048  p0  INs    0:00,05 -bash (bash)
61685  p0  SN+    0:05,13 /usr/bin/perl /home/.... cgi
61705  p0  ZN+    0:00,00  (perl5.8.6)
61732  p0  ZN+    0:00,00  (perl5.8.6)
61807  p0  ZN+    0:00,00  (perl5.8.6)
61812  p0  Z+     0:00,00  (perl5.8.6)
61840  p0  ZN+    0:00,00  (perl5.8.6)
61849  p0  ZN+    0:00,00  (perl5.8.6)
61850  p0  ZN+    0:00,00  (perl5.8.6)
61851  p0  ZN+    0:00,00  (perl5.8.6)
61856  p0  ZN+    0:00,00  (perl5.8.6)
61861  p0  Z+     0:00,00  (perl5.8.6)
61864  p0  ZN+    0:00,00  (perl5.8.6)
61865  p0  ZN+    0:00,00  (perl5.8.6)
61866  p0  Z+     0:00,00  (perl5.8.6)
61869  p0  Z+     0:00,00  (perl5.8.6)
61870  p0  Z+     0:00,00  (perl5.8.6)
61871  p0  ZN+    0:00,00  (perl5.8.6)
61874  p0  Z+     0:00,00  (perl5.8.6)
61875  p0  ZN+    0:00,00  (perl5.8.6)
61892  p0  Z+     0:00,00  (perl5.8.6)
61895  p0  ZN+    0:00,00  (perl5.8.6)
61896  p0  ZN+    0:00,00  (perl5.8.6)
61897  p0  ZN+    0:00,00  (perl5.8.6)
61899  p0  ZN+    0:00,00  (perl5.8.6)
61904  p0  Z+     0:00,00  (perl5.8.6)
61905  p0  ZN+    0:00,00  (perl5.8.6)
61906  p0  ZN+    0:00,00  (perl5.8.6)
61907  p0  ZN+    0:00,00  (perl5.8.6)
61910  p0  ZN+    0:00,00  (perl5.8.6)
61955  p0  ZN+    0:00,00  (perl5.8.6)
61956  p0  Z+     0:00,00  (perl5.8.6)
61959  p0  ZN+    0:00,00  (perl5.8.6)
61964  p0  ZN+    0:00,00  (perl5.8.6)
61972  p0  Z+     0:00,00  (perl5.8.6)
61973  p0  ZN+    0:00,00  (perl5.8.6)
61974  p0  Z+     0:00,00  (perl5.8.6)
62000  p0  ZN+    0:00,00  (perl5.8.6)
62001  p0  Z+     0:00,00  (perl5.8.6)
62004  p0  Z+     0:00,00  (perl5.8.6)
62013  p0  ZN+    0:00,00  (perl5.8.6)
62106  p0  Z+     0:00,00  (perl5.8.6)
62109  p0  Z+     0:00,00  (perl5.8.6)
62114  p0  Z+     0:00,00  (perl5.8.6)
62119  p0  ZN+    0:00,00  (perl5.8.6)
62123  p0  Z+     0:00,00  (perl5.8.6)
62126  p0  Z+     0:00,00  (perl5.8.6)
62127  p0  ZN+    0:00,00  (perl5.8.6)
62142  p0  Z+     0:00,00  (perl5.8.6)
62147  p0  ZN+    0:00,00  (perl5.8.6)
62152  p0  ZN+    0:00,00  (perl5.8.6)
62154  p0  ZN+    0:00,00  (perl5.8.6)
62157  p0  ZN+    0:00,00  (perl5.8.6)
62158  p0  Z+     0:00,00  (perl5.8.6)
62165  p0  Z+     0:00,00  (perl5.8.6)
62196  p0  Z+     0:00,00  (perl5.8.6)
62215  p0  ZN+    0:00,00  (perl5.8.6)
62218  p0  ZN+    0:00,00  (perl5.8.6)
62219  p0  Z+     0:00,00  (perl5.8.6)
62224  p0  ZN+    0:00,00  (perl5.8.6)
62235  p0  Z+     0:00,00  (perl5.8.6)
62238  p0  SN+    0:00,01 /usr/bin/perl /home/.... cgi
60083  p1  SNs    0:00,05 -bash (bash)
62239  p1  RN+    0:00,00 ps


Такое множество ZN+ и Z+ процессов создает perl сценарий в результате вызова fork. Каждый раз код в форке заканчивается вызовом функции exit. И при этом во время жизни процесса (сценария) существут только один поток-ребенок, но он порождается и умирате множество раз в цикле. В результате этого образуются хвосты хорошо видные в выше преведенном логе. Как избавиться от этих "зомби"? 

Из за таких хвостов сценарий вырубают автоматически на сервере моего хостера. 

Чего делать?


Автор: errr 2.7.2007, 21:57
perldoc perlipc


          use POSIX ":sys_wait_h";
           sub REAPER {
               my $child;
               # If a second child dies while in the signal handler caused by the
               # first death, we won’t get another signal. So must loop here else
               # we will leave the unreaped child as a zombie. And the next time
               # two children die we get another zombie. And so on.
               while (($child = waitpid(-1,WNOHANG)) > 0) {
                   $Kid_Status{$child} = $?;
               }
               $SIG{CHLD} = \&REAPER;  # still loathe sysV
           }
           $SIG{CHLD} = \&REAPER;
           # do something that forks...



Автор: vaddsm 3.7.2007, 10:52
Собственно зашел сказать что уже решил проблему даже в буфер вот это кинул:


Код

sub REAPER 
{
 my $child;
 while (($child = waitpid(-1,WNOHANG)) > 0) 
 {
  $Kid_Status{$child} = $?;
 }
 $SIG{CHLD} = \&REAPER; 
}

$SIG{CHLD} = \&REAPER;


А тут ответ на помосчь подоспел. Все равно спасибо errr за внимание!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)