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

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

Жанры

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

12 err_sys("getrusage error");

13 if (getrusage(RUSAGE_CHILDREN, &childusage) < 0)

14 err_sys("getrusage error");

15 user = (double)myusage.ru_utime.tv_sec +

16 myusage.ru_utime.tv_usec / 1000000.0;

17 user += (double)childusage.ru_utime.tv_sec +

18 childusage.ru_utime.tv_usec / 1000000.0;

19 sys = (double)myusage.ru_stime.tv_sec +

20 myusage.ru_stime.tv_usec / 1000000.0;

21 sys += (double)childusage.ru_stime.tv_sec +

22 childusage.ru_stime.tv_usec / 1000000.0;

21 printf("\nuser time = %g, sys time = %g\n", user, sys);

22 }

Функция

getrusage
вызывается
дважды: она позволяет получить данные об использовании ресурсов вызывающим процессом (
RUSAGE_SELF
) и всеми его дочерними процессами, которые завершили свое выполнение (
RUSAGE_CHILDREN
). Выводится время, затраченное центральным процессором на выполнение пользовательского процесса (общее пользовательское время, total user time), и время, которое центральный процессор затратил внутри ядра на выполнение задач, заданных вызывающим процессом (общее системное время, total system time).

Возвращаясь к листингу 30.2, мы видим, что для обработки каждого клиентского запроса вызывается функция

web_child
. Эта функция показана в листинге 30.5.

Листинг 30.5. Функция web_child: обработка каждого клиентского запроса

//server/web_child.c

1 #include "unp.h"

2 #define MAXN 16384 /* максимальное количество байтов, которое клиент

может запросить */

3 void

4 web_child(int sockfd)

5 {

6 int ntowrite;

7 ssize_t nread;

8 char line[MAXLINE], result[MAXN];

9 for (;;) {

10 if ((nread = Readline(sockfd, line, MAXLINE)) == 0)

11 return; /* соединение закрыто другим концом */

12 /* line задает, сколько байтов следует отправлять обратно */

13 ntowrite = atol(line);

14 if ((ntowrite <= 0) || (ntowrite > MAXN))

15 err_quit("client request for bytes", ntowrite);

16 Writen(sockfd, result, ntowrite);

17 }

18 }

Установив соединение с сервером, клиент записывает одну строку, задающую количество байтов, которое сервер должен вернуть. Это отчасти похоже на HTTP: клиент отправляет небольшой запрос, а сервер в ответ отправляет требуемую информацию (часто это файл HTML или изображение GIF). В случае HTTP сервер обычно закрывает соединение после отправки клиенту затребованных данных, хотя более новые версии используют постоянные соединения( persistent connection), оставляя соединения TCP открытыми для дополнительных клиентских запросов. В нашей функции

web_child
сервер допускает дополнительные запросы от клиента, но, как мы видели в листинге 24.1, клиент посылает серверу только по одному запросу на каждое соединение, а по получении ответа от сервера это соединение закрывается.

В строке 1 табл. 30.1 показаны результаты измерения времени, затраченного параллельным сервером. При сравнении со следующими строками этой таблицы видно, что параллельный сервер тратит больше процессорного времени, чем все другие

типы серверов — то, что мы и ожидали при вызове функции
fork
.

ПРИМЕЧАНИЕ

Один из способов устройства сервера, который мы не рассматриваем в этой главе, — это сервер, инициируемый демоном inetd (см. раздел 13.5). С точки зрения управления процессами такой сервер подразумевает использование функций fork и exec, так что затраты времени центрального процессора будут еще больше, чем показанные в строке 1 для параллельного сервера.

30.6. Сервер TCP с предварительным порождением процессов без блокировки для вызова accept

В первом из рассматриваемых нами «усовершенствованных» серверов используется технология, называемая предварительным созданием процессов( preforking). Вместо того чтобы вызывать функцию

fork
каждый раз при поступлении очередного запроса от клиента, сервер создает при запуске некоторое количество дочерних процессов, и впоследствии они обслуживают клиентские запросы по мере установления соединений с клиентами. На рис. 30.1 показан сценарий, при котором родитель предварительно создал Nдочерних процессов, и в настоящий момент имеется два соединения с клиентами.

Рис. 30.1. Предварительное создание дочерних процессов сервером

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

fork
родительским процессом, тем самым стоимость этого обслуживания понижается. Недостатком же является необходимость угадать, сколько дочерних процессов нужно создать при запуске. Если в некоторый момент времени количество имеющихся дочерних процессов будет равно количеству обслуживаемых клиентов, то дополнительные клиентские запросы будут игнорироваться до того момента, когда освободится какой-либо дочерний процесс. Но, как сказано в разделе 4.5, клиентские запросы в такой ситуации игнорируются не полностью. Для каждого из этих дополнительных клиентов ядро выполнит трехэтапное рукопожатие (при этом общее количество соединений не может превышать значения аргумента
backlog
функции
listen
), и при вызове функции
accept
установленные соединения будут переданы серверу. При этом, однако, приложение-клиент может заметить некоторое ухудшение в скорости получения ответа, так как, хотя функция
connect
может быть выполнена сразу же, запрос может не поступать на обработку еще некоторое время.

За счет некоторого дополнительного усложнения кода всегда можно добиться того, что сервер справится со всеми клиентскими запросами. От родительского процесса требуется постоянно отслеживать количество свободных дочерних процессов, и если это количество падает ниже некоторого минимального предела, родитель должен вызвать функцию

fork
и создать недостающее количество дочерних процессов. Аналогично, если количество свободных дочерних процессов превосходит некоторую максимальную величину, некоторые из этих процессов могут быть завершены родителем, так как излишнее количество свободных дочерних процессов тоже отрицательно влияет на производительность (об этом мы поговорим чуть позже).

Но прежде чем углубляться в детали, исследуем основную структуру этого типа сервера. В листинге 30.6 показана функция

main
для первой версии нашего сервера с предварительным порождением дочерних процессов.

Листинг 30.6. Функция main сервера с предварительным порождением дочерних процессов

//server/serv02.c

1 #include "unp.h"

2 static int nchildren;

3 static pid_t *pids;

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

Отмороженный 8.0

Гарцевич Евгений Александрович
8. Отмороженный
Фантастика:
постапокалипсис
рпг
аниме
5.00
рейтинг книги
Отмороженный 8.0

Газлайтер. Том 14

Володин Григорий Григорьевич
14. История Телепата
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Газлайтер. Том 14

Ермак. Телохранитель

Валериев Игорь
2. Ермак
Фантастика:
альтернативная история
7.00
рейтинг книги
Ермак. Телохранитель

Матабар IV

Клеванский Кирилл Сергеевич
4. Матабар
Фантастика:
фэнтези
5.00
рейтинг книги
Матабар IV

Сборник коротких эротических рассказов

Коллектив авторов
Любовные романы:
эро литература
love action
7.25
рейтинг книги
Сборник коротких эротических рассказов

Идеальный мир для Лекаря 19

Сапфир Олег
19. Лекарь
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 19

Дочь моего друга

Тоцка Тала
2. Айдаровы
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Дочь моего друга

Свет Черной Звезды

Звездная Елена
6. Катриона
Любовные романы:
любовно-фантастические романы
5.50
рейтинг книги
Свет Черной Звезды

Кодекс Крови. Книга IV

Борзых М.
4. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга IV

Идеальный мир для Лекаря 22

Сапфир Олег
22. Лекарь
Фантастика:
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Идеальный мир для Лекаря 22

Попаданка в академии драконов 4

Свадьбина Любовь
4. Попаданка в академии драконов
Любовные романы:
любовно-фантастические романы
7.47
рейтинг книги
Попаданка в академии драконов 4

Сердце Дракона. Том 12

Клеванский Кирилл Сергеевич
12. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.29
рейтинг книги
Сердце Дракона. Том 12

Лолита

Набоков Владимир Владимирович
Проза:
классическая проза
современная проза
8.05
рейтинг книги
Лолита

Сводный гад

Рам Янка
2. Самбисты
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Сводный гад