Способ 2 - Параллельный сервер с предварительным созданием копий

Второй способ является модификацией первого и применяется в приложениях, требующих мапой задержки(латентности) между моментом первого запроса и ответа сервера. Нужно только поменять fork & accept местами - создать заранее некоторый пул обслуживающих процессов, каждый из которых до прихода клиентского запроса будет заблокирован на accept (accept на одном и том же прослушиваемом сокете). А после отработки клиентского запроса заблаговременно создать новый обслуживающий процесс. Эта техника известна как «предварительный fork» или pre-fork.

Фрагмент кода программы сервера с использованием этой методики показан в листинге 2. Для более четкого показа приводится код программы на C++.

Листинг 2. Код сервер (версия pre- fork)

#include <common.h>

Const int NUMPROC = 3;

int main(int argc, char *argv[])

{

int ls = getsocket(PREFORK_PORT), rs;

for(int i = 0; i < NUMPROC; i++) {

if(fork() == 0) {

int rs;

while(true) {

if((rs = accept(ls, NULL, NULL)) < 0) errx("accept error");

server(rs); /* В подпрограмме server реализуется логика работы сервера */

close(rs);

cout << i << flush;

delay(250);

};

};

};

for(int i = 0; i < NUMPROC; i++) waitpid(0, NULL, 0);

exit(EXIT_SUCCESS);

}

При написании этого текста я несколько «схитрил» и упростил в сравнении с предложенной абзацем выше моделью. Здесь 3 обслуживающих процесса сделаны циклическими и не завершаются по окончанию обслуживания, а снова блокируются на accept, но для наблюдения эффектов этого вполне достаточно (последняя строка нужна вообще только для блокировки родительского процесса, и «сохранения» управляющего терминала - для возможности прекращения всей группы процессов по ^C или по kill -TERM... в случае, когда сервер запущен в фоновом режиме).


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: