Код Web-cepвepa с предварительным, формированием потоков, имеет больший объем, нежели простой многопоточный сервер. Это свидетельствует о том, что для координации работы многочисленных потоков должен применяться гораздо более сложный код. Проведем анализ программы.
Строки 1-8. Загрузка модулей. Загружаются модули IO::Socket, IO::File и IO::Select, а также Thread. Модуль Thread не импортирует функции cond_wait () и cond_broadcast () по умолчанию, поэтому они импортируются явно.
Строки 9-14. Определение констант. Определяются различные константы, используемые сервером, включая константу prethread со значением числа потоков, которые должны быть запущены в начале работы сервера; константы со значением верхней и нижней отметок, которые имеют тот же смысл, что и в серверах с предварительным ветвлением; и флажок debug для включения отладочных сообщений. Определена также константа max_request, которая управляет тем, какое число транзакций должен принять поток, прежде чем самостоятельно завершит работу.
Строки 15-18. Объявление глобальных переменных. Переменная $accept_lock, как было описано ранее, используется для защиты функции accept () — чтобы только один поток одновременно мог принимать входящие запросы на установление соединения из приемного сокета. Хеш % status содержит информацию о состоянии каждого потока, которая хранится под ключом, соответствующим идентификатору этого потока, а $status представляет собой условную переменную, применяемую и для блокировки хеша % status, и для указания на то, что он изменился. Переменная $done указывает главному потоку, что должен быть выполнен останов сервера.