//server/pr_cpu_time.c
1 #include "unp.h"
2 #include
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 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 сервер обычно закрывает соединение после отправки клиенту затребованных данных, хотя более новые версии используют web_child
сервер допускает дополнительные запросы от клиента, но, как мы видели в листинге 24.1, клиент посылает серверу только по одному запросу на каждое соединение, а по получении ответа от сервера это соединение закрывается.
В строке 1 табл. 30.1 показаны результаты измерения времени, затраченного параллельным сервером. При сравнении со следующими строками этой таблицы видно, что параллельный сервер тратит больше процессорного времени, чем все другие типы серверов — то, что мы и ожидали при вызове функции fork
.
Вильям Л Саймон , Вильям Саймон , Наталья Владимировна Макеева , Нора Робертс , Юрий Викторович Щербатых
Зарубежная компьютерная, околокомпьютерная литература / ОС и Сети, интернет / Короткие любовные романы / Психология / Прочая справочная литература / Образование и наука / Книги по IT / Словари и Энциклопедии