1. Perl / Говнокод #5244

    −116

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    6. 6
    7. 7
    8. 8
    9. 9
    sub child_handler {
            #wait end of the child process
            my $waitedpid = wait;
            delete $my_childs{$waitedpid};
            $SIG{CHLD} = \&child_handler;
            LOG ("ripped $waitedpid" . ($? ? " with exit $?" : '')) if ($main::DEBUG>0);
    }
    
    $SIG{CHLD} = \&child_handler;

    Тарификатор плодящий зомби.
    Автор не поленился переустановить обработчик для сигнала.. хотя это не нужно. Всем читать учебники - как правильно рипать чайлдов в цикле.
    (с) Руслан Залата

    Запостил: SanityIO, 12 Января 2011

    Комментарии (5) RSS

    • > Всем читать учебники

      подскажите учебники где такому учат?

      я как бы по профилю системщик, мне после пары зомби эта фишка почти сразу ясна стала. но вот коллеги они в лучшем случае прикладники - я им задолбался такие вещи разжевывать. вот уже третий раз им объяснял давече что TCP и UDP порты это разные порты и на том же самом порту можно и TCP и UDP сервер держать. а они все сомневаются, даже не смотря на то что работает, покаж им дескать мануал.
      Ответить
      • Стивенс - "UNIX. Профессиональное программирование" например.
        Да даже в кэмелбуке или в кукбуке для перла - я уверен есть.
        Ответить
    • Пожалуй, сКЭПлю немного, и поясню, для тех, кто не знает про зомби процессы в Unix-системах, дабы говнокод стал всем понятен.

      Процесс при завершении освобождает все свои ресурсы (за исключением PID — идентификатора процесса) и становится «зомби» — пустой записью в таблице процессов, хранящей код завершения для родительского процесса.

      Система уведомляет родительский процесс о завершении дочернего с помощью сигнала SIGCHLD. Предполагается, что после получения SIGCHLD он считает код возврата с помощью системного вызова wait(), после чего запись зомби будет удалена из списка процессов.

      Если родительский процесс игнорирует SIGCHLD (а он игнорируется по умолчанию), то зомби остаются до его завершения.
      Ответить
      • SIGCHLDов может прийти несколько до того как обработчик сигнала будет запущен.. а запущен он будет всего один раз.. о песледсвиях подумайте сами.
        Ответить
        • > а запущен он будет всего один раз..

          так как очередь/буффер для сигналов процесса (signal queueing) весьма короткая (Линух может буфферить до 3х сигналов одного типа).

          и по POSIX, ОСь вообще и не обязана реализовывать очередь сигналов.

          поэтому цикл внутри обработчика SIGCHLD вокруг waitpid(WNOHANG) обязателен, т.к. SIGCHLDы могут быть потеряны из-за переполнения очереди сигналов.
          Ответить

    Добавить комментарий