Чтение онлайн

на главную - закладки

Жанры

UNIX: разработка сетевых приложений
Шрифт:

Мы не приводим код для последовательного сервера, так как он представляет собой тривиальную модификацию параллельного сервера, показанного в следующем разделе.

30.5. Параллельный сервер TCP: один дочерний процесс для каждого клиента

Традиционно параллельный сервер TCP вызывает функцию

fork
для порождения нового дочернего процесса, который будет выполнять обработку очередного клиентского запроса. Это позволяет серверу обрабатывать несколько запросов одновременно, выделяя по одному дочернему процессу для каждого клиента. Единственным ограничением
на количество одновременно обрабатываемых клиентских запросов является ограничение операционной системы на количество дочерних процессов, допустимое для пользователя, в сеансе которого работает сервер. Листинг 5.9 содержит пример параллельного сервера, и большинство серверов TCP написаны в том же стиле.

Проблема с параллельными серверами заключается в количестве времени, которое тратит центральный процессор на выполнение функции

fork
для порождения нового дочернего процесса для каждого клиента. Давным-давно, в конце 80-х годов XX века, когда наиболее загруженные серверы обрабатывали сотни или тысячи клиентов за день, это было приемлемо. Но расширение Сети изменило требования. Теперь загруженными считаются серверы, обрабатывающие миллионы соединений TCP в день. Сказанное относится лишь к одиночным узлам, но наиболее загруженные сайты используют несколько узлов, распределяя нагрузку между ними (в разделе 14.2 [112] рассказывается об общепринятом способе распределения этой нагрузки, называемом циклическим обслуживанием DNS — DNS round robin). В последующих разделах описаны различные способы, позволяющие избежать вызова функции
fork
для каждого клиентского запроса, но тем не менее параллельные серверы остаются широко распространенными.

В листинге 30.2 показана функция

main
для нашего параллельного сервера TCP.

Листинг 30.2. Функция main для параллельного сервера TCP

//server/serv01.c

1 include "unp.h"

2 int

3 main(int argc, char **argv)

4 {

5 int listenfd, connfd;

6 pid_t childpid;

7 void sig_chld(int), sig_int(int), web_child(int);

8 socklen_t clilen, addrlen;

9 struct sockaddr *cliaddr;

10 if (argc == 2)

11 listenfd = Tcp_listen(NULL, argv[1], &addrlen);

12 else if (argc == 3)

13 listenfd = Tcp_listen(argv[1], argv[2], &addrlen);

14 else

15 err_quit("usage: serv01 [ <host> ] <port#>");

16 cliaddr = Malloc(addrlen);

17 Signal(SIGCHLD, sig_chld);

18 Signal(SIGINT, sig_int);

19 for (;;) {

20 clilen = addrlen;

21 if ((connfd = accept(listenfd, cliaddr, &clilen)) < 0) {

22 if (errno == EINTR)

23 continue; /*
назад к for */

24 else

25 err_sys("accept error");

26 }

27 if ((childpid = Fork) == 0) { /* дочерний процесс */

28 Close(listenfd); /* закрываем прослушиваемый сокет */

29 web_child(connfd); /* обрабатываем запрос */

30 exit(0);

31 }

32 Close(connfd); /* родительский процесс закрывает

присоединенный сокет */

33 }

34 }

Эта функция аналогична функции, показанной в листинге 5.9: она вызывает функцию

fork
для каждого клиентского соединения и обрабатывает сигналы
SIGCHLD
, приходящие от закончивших свое выполнение дочерних процессов. Тем не менее мы сделали эту функцию не зависящей от протокола за счет вызова функции
tcp_listen
. Мы не показываем обработчик сигнала
sig_chld
: он совпадает с показанным в листинге 5.8, но только без функции
printf
.

Мы также перехватываем сигнал

SIGINT
, который генерируется при вводе символа прерывания. Мы вводим этот символ после завершения работы клиента, чтобы было выведено время, потраченное центральным процессором на выполнение данной программы. В листинге 30.3 показан обработчик сигнала. Это пример обработчика сигнала, который никогда не возвращает управление.

Листинг 30.3. Обработчик сигнала SIGINT

//server/serv01.c

35 void

36 sig_int(int signo)

37 {

38 void pr_cpu_time(void);

39 pr_cpu_time;

40 exit(0);

41 }

В листинге 30.4 показана функция

pr_cpu_time
, вызываемая из обработчика сигнала.

Листинг 30.4. Функция pr_cpu_time: вывод полного времени центрального процессора

//server/pr_cpu_time.c

1 #include "unp.h"

2 #include <sys/resource.h>

3 #ifndef HAVE_GETRUSAGE_PROTO

4 int getrusage(int, struct rusage*);

5 #endif

6 void

7 pr_cpu_time(void)

8 {

9 double user, sys;

10 struct rusage myusage, childusage;

11 if (getrusage(RUSAGE_SELF, &myusage) < 0)

Поделиться:
Популярные книги

В зоне особого внимания

Иванов Дмитрий
12. Девяностые
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
В зоне особого внимания

Сильнейший ученик. Том 2

Ткачев Андрей Юрьевич
2. Пробуждение крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Сильнейший ученик. Том 2

Нищенка в элитной академии

Зимина Юлия
4. Академия юных сердец
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Нищенка в элитной академии

Назад в СССР 5

Дамиров Рафаэль
5. Курсант
Фантастика:
попаданцы
альтернативная история
6.64
рейтинг книги
Назад в СССР 5

Столичный доктор. Том III

Вязовский Алексей
3. Столичный доктор
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Столичный доктор. Том III

Секретарша генерального

Зайцева Мария
Любовные романы:
современные любовные романы
эро литература
короткие любовные романы
8.46
рейтинг книги
Секретарша генерального

Мастер Разума III

Кронос Александр
3. Мастер Разума
Фантастика:
героическая фантастика
попаданцы
аниме
5.25
рейтинг книги
Мастер Разума III

Идеальный мир для Социопата 3

Сапфир Олег
3. Социопат
Фантастика:
боевая фантастика
6.17
рейтинг книги
Идеальный мир для Социопата 3

Ученик

Первухин Андрей Евгеньевич
1. Ученик
Фантастика:
фэнтези
6.20
рейтинг книги
Ученик

Попытка возврата. Тетралогия

Конюшевский Владислав Николаевич
Попытка возврата
Фантастика:
альтернативная история
9.26
рейтинг книги
Попытка возврата. Тетралогия

Ищу жену для своего мужа

Кат Зозо
Любовные романы:
любовно-фантастические романы
6.17
рейтинг книги
Ищу жену для своего мужа

Сила рода. Том 3

Вяч Павел
2. Претендент
Фантастика:
фэнтези
боевая фантастика
6.17
рейтинг книги
Сила рода. Том 3

Крестоносец

Ланцов Михаил Алексеевич
7. Помещик
Фантастика:
героическая фантастика
попаданцы
альтернативная история
5.00
рейтинг книги
Крестоносец

На границе империй. Том 10. Часть 4

INDIGO
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 4