Самое простое решение этой проблемы опять-таки состоит в использовании функции select () для ожидания готовности канала к чтению, поскольку перезапуск этой функции не выполняется автоматически. Для ожидания готовности канала к чтению вызывается метод can_read () объекта IO::Select, а затем для чтения текущего содержимого канала в буфер применяется функция sysread (). Считанные данные могут содержать одно или несколько сообщений, в зависимости от активности дочерних процессов. Данные разбиваются на отдельные сообщения в местах вхождения символов обозначения конца строки, и сообщения интерпретируются. Если дочерний процесс выдал код состояния “done”, его идентификатор удаляется из глобального хеша % status. В ином случае содержимое глобального хеша обновляется путем записи текущего кода состояния дочернего процесса.
Строки 43-52. Запуск или уничтожение дочерних процессов. После обновления хеша %status создается список простаивающих дочерних процессов с использованием функции grep() для извлечения из хеша %status информации о дочерних процессах, имеющих код состояния “idle”. Если число простаивающих дочерних процессов ниже установленного константой lo_water_mark, вызывается подпрограмма make_new_child () столько раз, сколько требуется для повышения числа дочерних процессов до желаемого уровня. Если число простаивающих дочерних процессов превышает значение hi_water_mark, то лишним дочерним процессам направляется корректное указание, что они должны завершить работу, в форме сигнала hup (сокращение от hangup).