Схема организации процессов 2

Опубликовано в Технологии > Серверные технологии

На рис. 11.1 показана схема организации процессов параллельного сервера с установлением логического соединения, в котором используются однопотоковые процессы. Как показано на этом рисунке, ведущий процесс непосредственно не взаимодействует с клиентами. По существу, в его задачу входит просто ожидание поступления очередного запроса на установление соединения через общепринятый порт. После поступления такого запроса система возвращает новый дескриптор сокета, предназначенный для использования с этим соединением. Ведущий процесс создает ведомый процесс для обслуживания соединения и предоставляет возможность ведомому процессу работать параллельно с ним. В любое время в сервере функционирует один ведущий процесс, а число ведомых процессов может составлять от нуля и более. Ведущий процесс сервера принимает каждый входящий запрос на установление соединения и создает ведомый процесс для его обслуживания. Продаем участки. Лодочный причал на даче. Подходящая площадь участка.

Для получения очередного запроса на установление соединения из общепринятого порта используется блокирующий вызов функции accept, что позволяет предотвратить бесполезное расходование ресурсов процессора во время ожидания очередных запросов на установление соединения в ведущем процессе сервера. Поэтому, в отличие от последовательного сервера, описанного в главе 10, ведущий процесс сервера в параллельном сервере основную часть времени проводит в состоянии, заблокированном в вызове функции accept. После поступления запроса на установление соединения выполняется возврат управления функцией accept, а ведущий процесс получает возможность продолжить выполнение. Ведущий процесс создает ведомый процесс для обработки запроса и снова вызывает функцию accept. В этом вызове ведущий процесс в очередной раз блокируется до поступления еще одного запроса на установление соединения.

Схема организации процессов параллельного сервера с установлением логического соединения, в котором используются однопотоковые процессы

11.5. Пример параллельного сервера ECHO

Код сервера ECHO, в котором используются параллельные процессы для одновременного обслуживания нескольких клиентов, приведен в файле TCPechod.c.

Как показано в этом примере, вызовы функций, обеспечивающих параллельную работу, занимают лишь небольшую часть кода. Ведущий процесс сервера начинает свое выполнение в главной процедуре. После проверки параметров в ведущем процессе сервера вызывается процедура passiveTCP, которая создает пассивный сокет для общепринятого порта протокола, а затем входит в бесконечный цикл. Символическая константа QLEN, передаваемая в качестве второго параметра процедуры passiveTCP, задает максимальное число дополнительных входящих запросов на установление соединений TCP, которые будут поставлены в очередь, пока сервер занимается обслуживанием текущего соединения.

При каждом проходе по циклу ведущий сервер вызывает функцию accept для перехода в состояние ожидания запроса на установление соединения от клиента. Как и в последовательном сервере, этот вызов блокируется до поступления запроса. После получения программным обеспечением базового протокола TCP запроса на установление соединения операционная система создает сокет для нового соединения и вызов функции accept возвращает дескриптор этого сокета.

После возврата управления из функции accept ведущий процесс сервера создает ведомый процесс для обслуживания соединения. Для этого ведущий процесс вызывает функцию fork, чтобы разделиться на два процесса . Поток во вновь созданном дочернем процессе вначале закрывает сокет ведущего процесса, а затем вызывает процедуру TCPechod для обслуживания соединения. Поток в родительском процессе закрывает сокет, который был создан для обслуживания нового соединения, и продолжает выполнение бесконечного цикла. При следующем проходе по циклу ведущий процесс после вызова функции accept снова переходит в состояние ожидания очередных запросов на установление соединения. Следует отметить, что и первоначальный, и новые процессы имеют доступ к открытым сокетам после вызова функции fork() и что они оба должны закрыть один из этих сокетов, после чего система освобождает связанный с ним ресурс. Поэтому этот сокет закрывается только в ведущем процессе после вызова функции close потоком ведущего процесса для закрытия сокета нового соединения. Аналогичным образом, когда поток в ведомом процессе вызывает функцию close для закрытия сокета ведущего процесса, этот сокет закрывается только в ведомом процессе. Ведомый процесс продолжает получать доступ к сокету нового соединения до тех пор, пока не завершит свою работу, а ведущий сервер продолжает иметь доступ к сокету, который соответствует общепринятому порту.

После закрытия сокета ведущего процесса ведомый процесс вызывает процедуру TCPechod, которая предоставляет услуги службы ECHO для одного соединения. Процедура TCPechod состоит из цикла, который повторно вызывает функцию read для приема данных из соединения, а затем вызывает функцию write для обратной передачи тех же данных через это соединение. Как правило, функция read возвращает (положительное) число считанных байтов. Она возвращает значение меньше нуля, если произошла ошибка (например, если разорвано сетевое соединение между клиентом и сервером), или нуль, если обнаружен признак конца файла (т.е. из этого сокета нельзя больше получать данные). Аналогичным образом, функция write обычно возвращает число переданных символов, но возвращает значение меньше нуля при возникновении ошибки. В ведомом процессе проверяются коды возврата и используется функция errexit для вывода сообщения, если возникла ошибка.

Процедура TCPechod возвращает нуль, если ей удалось выполнить эхо-повтор всех данных без ошибок. После возврата управления процедурой TCPechod ведомый процесс использует возвращенное значение в качестве параметра вызова функции exit. Система Linux интерпретирует вызов функции exit как требование завершить процесс и использует параметр вызова этой функции как код завершения процесса. В соответствии с общепринятым соглашением, в процессе для обозначения нормального завершения используется код завершения нуль. Это означает, что после предоставления услуг службы ECHO ведомый процесс окончился нормально. После прекращения работы ведомого процесса операционная система автоматически закрывает все его открытые дескрипторы, в том числе дескриптор соединения TCP.

Похожие статьи