Следующий фрагмент кода можно встретить во многих серверных сценариях.
$SIG {CHLD} = sub { wait () ; }
Смысл этого оператора сводится к тому, что функция wait () вызывается каждый раз, когда сервер получает сигнал CHLD, после чего соответствующий дочерний процесс, например, поток информации к принтеру lp 2824 немедленно убирается из таблицы процессов, а код результата игнорируется. Как правило, этот оператор выполняется успешно, но иногда его работа нарушается, например при останове или перезапуске дочернего процесса по сигналу. В этом случае родительский процесс получает сигнал CHLD, но фактически здесь не происходит завершения ни одного дочернего процесса. Функция wait () переходит в состояние ожидания на неопределенное время и приводит к останову сервера — такое развитие событий является нежелательным.
Еще одна ситуация, которая может нарушить работу этого несложного обработчика сигнала, — почти одновременное завершение двух или более дочерних процессов. Механизм распространения сигналов системы UNIX способен в любой момент обрабатывать только один сигнал конкретного типа. Два события завершения будут увязаны в единственное событие CHLD и доставлены серверу. Несмотря на то что нужно будет убрать два дочерних процесса, сервер вызовет функцию wait () только один раз и оставит зомби. Эта утечка ресурсов, связанная с наличием зомби, становится заметной по истечении достаточно продолжительного периода времени.
Последняя нежелательная ситуация — когда родительский процесс выполняет вызовы, которые приводят к порождению подпроцессов, в частности вызова с использованием оператора обратных одинарных кавычек функции system () и функции open () открытия канала. Для этих функций интерпретатор Perl берет на себя вызов функции wait () перед возвращением основной части кода. Однако на некоторых платформах “проскакивают” лишние сигналы CHLD, даже несмотря на то что нет неубранных дочерних процессов, Для которых должна быть вызвана функция wait (), поэтому вызов этой функции снова зависает.