Шрифт:
Упражнения
1. Каково назначение флага
2. При работе программы
Глава 30
Альтернативное устройство клиента и сервера
30.1. Введение
При написании сервера под Unix мы можем выбирать из следующих вариантов управления процессом:
Наш первый сервер, показанный в листинге 1.5, был последовательным( iterative), но количество сценариев, для которых этот вариант является предпочтительным, весьма ограничено, поскольку последовательный сервер не может начать обработку очередного клиентского запроса, не закончив полностью обработку текущего запроса.
В листинге 5.1 показан первый в данной книге параллельный( concurrent) сервер, который для обработки каждого клиентского запроса порождал дочерний процесс с помощью функции
В разделе 6.8 мы разработали другую версию сервера TCP, в котором имеется только один процесс, обрабатывающий любое количество клиентских запросов с помощью функции
В листинге 26.2 мы модифицировали параллельный сервер, создав для каждого клиента по одному потоку вместо одного процесса.
В этой главе мы рассмотрим два других способа модификации устройства параллельного сервера.
Предварительное создание дочерних процессов( preforking). В этом случае при запуске сервера выполняется функция
Предварительное создание потоков( prethreading). При запуске сервера создается некоторое количество (пул) потоков, и для обработки каждого клиента используется поток из данного набора.
В данной главе мы будем рассматривать множество вопросов, связанных с предварительным созданием потоков и процессов. Например, что произойдет, если в пуле окажется недостаточное количество процессов или потоков? А если их будет слишком много? Как родительский и дочерние процессы (или потоки) синхронизируют свои действия?
Обычно написать клиент легче, чем сервер, за счет простоты управления процессом клиента. Тем не менее мы уже исследовали различные способы написания простого эхо-клиента, которые вкратце изложены в разделе 30.2.
В этой главе мы рассматриваем девять различных способов устройства сервера и взаимодействие каждого из этих серверов с одним и тем же клиентом. Клиент-серверный сценарий типичен для WWW: клиент посылает небольшой по объему запрос, а сервер отвечает ему, отсылая соответствующие запросу данные. Некоторые из этих серверов мы уже достаточно подробно обсуждали (например, параллельный сервер, вызывающий функцию
Мы запускали различные экземпляры клиента с каждым сервером, измеряя время, которое процессор тратит на обслуживание определенного количества клиентских запросов. Чтобы информация об этом не оказалась рассеянной по всей главе, мы свели все полученные результаты в табл. 30.1, на которую в этой главе будем неоднократно ссылаться. Следует отметить, что значения времени, указанные в этой таблице, соответствуют процессорному времени, затраченному только на управление процессом, так как из фактического значения времени процессора мы вычитаем время, которое тратит на выполнение того же задания последовательный сервер, не имеющий накладных расходов, связанных с управлением процессом. Иными словами, нулевой точкой отсчета в данной таблице для нас является время, затраченное последовательным сервером. Для большей наглядности мы включили в таблицу строку для последовательного сервера с нулевыми значениями времени. В этой главе термином время центрального процессора на управление процессом( process control CPU time) мы обозначаем разность между фактическим значением времени центрального процессора и временем, затраченным последовательным сервером, для каждой конкретной системы.
Таблица 30.1. Сравнительные значения времени, затраченного каждым из обсуждаемых в данной главе сервером
Описание сервера | Время центрального процессора на управление процессом | |
---|---|---|
0 | Последовательный (точка отсчета; затраты на управление процессом отсутствуют) | 0,0 |
1 | Параллельный сервер, один вызов функции fork для обработки одного клиента | 20,90 |