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

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

Жанры

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

3 main(int argc, char **argv)

4 {

5 int listenfd, connfd;

6 void sig_int(int);

7 void *doit(void*);

8 pthread_t tid;

9 socklen_t clilen, addrlen;

10 struct sockaddr *cliaddr;

11 if (argc == 2)

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

13 else if (argc == 3)

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

15 else

16 err_quit("usage: serv06 [ <host> ] <port#>");

17 cliaddr = Malloc(addrlen);

18 Signal (SIGINT, sig_int);

19 for (;;) {

20 clilen = addrlen;

21 connfd = Accept(listenfd, cliaddr, &clilen);

22 Pthread_create(&tid, NULL, &doit, (void*)connfd);

23 }

24 }

25 void*

26 doit(void *arg)

27 {

28 void web_child(int);

29 Pthread_detach(pthread_self);

30 web_child((int)arg);

31 Close((int)arg);

32 return (NULL);

33 }

Цикл
основного потока

19-23
Основной поток блокируется в вызове функции accept, и каждый раз, когда прибывает новое клиентское соединение, функцией
pthread_create
создается новый поток. Функция, выполняемая новым потоком, — это функция
doit
, а ее аргументом является присоединенный сокет.

Функция прочих потоков

25-33
Функция
doit
выполняется как отсоединенный (detached) поток, потому что основному потоку не требуется ждать ее завершения.
Doit
вызывает функцию
web_child
(см. листинг 30.5). Когда эта функция возвращает управление, присоединенный сокет закрывается.

Из табл. 30.1 мы видим, что эта простая версия с использованием потоков является более быстродействующей, чем даже самая быстрая из версий с предварительным порождением процессов. Кроме того, эта версия, в которой каждый клиент обслуживается одним потоком, во много раз быстрее версии, в которой каждый клиент обслуживается специально созданным для него дочерним процессом (первая строка табл. 30.1).

ПРИМЕЧАНИЕ

В разделе 26.5 мы упомянули о трех вариантах преобразования функции, которая не является безопасной в многопоточной среде, в функцию, обеспечивающую требуемую безопасность. Функция web_child вызывает функцию readline, и версия, показанная в листинге 3.12, не является безопасной в многопоточной среде. На примере, приведенном в листинге 30.20, были испробованы вторая и третья альтернативы из раздела 26.5. Увеличение быстродействия при переходе от альтернативы 3 к альтернативе 2 составило менее одного процента, вероятно, потому, что функция readline использовалась лишь для считывания значения счетчика (5 символов) от клиента. Поэтому в данной главе для простоты мы использовали более медленную версию из листинга 3.11 для сервера

с предварительным порождением потоков.

30.11. Сервер TCP с предварительным порождением потоков, каждый из которых вызывает accept

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

fork
. Для систем, поддерживающих потоки, логично предположить, что имеется та же закономерность: быстрее сразу создать пул потоков при запуске сервера, чем создавать по одному потоку по мере поступления запросов от клиентов. Основная идея такого сервера заключается в том, чтобы создать пул потоков, каждый из которых вызывает затем функцию
accept
. Вместо того чтобы блокировать потоки в вызове
accept
, мы используем взаимное исключение, как в разделе 30.8. Это позволяет вызывать функцию accept только одному потоку в каждый момент времени. Использовать блокировку файла для защиты
accept
в таком случае бессмысленно, так как при наличии нескольких потоков внутри данного процесса можно использовать взаимное исключение.

В листинге 30.21 показан заголовочный файл

pthread07.h
, определяющий структуру
Thread
, содержащую определенную информацию о каждом потоке.

Листинг 30.21. Заголовочный файл pthread07.h

//server/pthread07.h

1 typedef struct {

2 pthread_t thread_tid; /* идентификатор потока */

3 long thread_count; /* количество обработанных запросов */

4 } Thread;

5 Thread *tptr; /* массив структур Thread */

6 int listenfd, nthreads;

7 socklen_t addrlen;

8 pthread_mutex_t mlock;

Мы также объявляем несколько глобальных переменных, таких как дескриптор прослушиваемого сокета и взаимное исключение, которые должны совместно использоваться всеми потоками.

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

main
.

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

//server/serv07.c

1 #include "unpthread.h"

2 #include "pthread07.h"

3 pthread_mutex_t mlock = PTHREAD_MUTEX_INITIALIZER;

4 int

5 main(int argc, char **argv)

6 {

7 int i;

8 void sig_int(int), thread_make(int);

9 if (argc == 3)

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

11 else if (argc == 4)

12 listenfd = Tcp_1isten(argv[1], argv[2], &addrlen);

13 else

14 err_quit("usage: serv07 [ <host> ] <port#> <#threads>");

15 nthreads = atoi(argv[argc - 1]);

16 tptr = Calloc(nthreads, sizeof(Thread));

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

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

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

На Ларэде

Кронос Александр
3. Лэрн
Фантастика:
фэнтези
героическая фантастика
стимпанк
5.00
рейтинг книги
На Ларэде

Охота на попаданку. Бракованная жена

Герр Ольга
Любовные романы:
любовно-фантастические романы
5.60
рейтинг книги
Охота на попаданку. Бракованная жена

Кай из рода красных драконов

Бэд Кристиан
1. Красная кость
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Кай из рода красных драконов

Хозяйка Проклятой Пустоши. Книга 2

Белецкая Наталья
2. Хозяйка Проклятой Пустоши
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Хозяйка Проклятой Пустоши. Книга 2

Безумный Макс. Поручик Империи

Ланцов Михаил Алексеевич
1. Безумный Макс
Фантастика:
героическая фантастика
альтернативная история
7.64
рейтинг книги
Безумный Макс. Поручик Империи

Потусторонний. Книга 2

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

Чапаев и пустота

Пелевин Виктор Олегович
Проза:
современная проза
8.39
рейтинг книги
Чапаев и пустота

Солнечный корт

Сакавич Нора
4. Все ради игры
Фантастика:
зарубежная фантастика
5.00
рейтинг книги
Солнечный корт

Лютая

Шёпот Светлана Богдановна
Любовные романы:
любовно-фантастические романы
6.40
рейтинг книги
Лютая

Ведьмак (большой сборник)

Сапковский Анджей
Ведьмак
Фантастика:
фэнтези
9.29
рейтинг книги
Ведьмак (большой сборник)

Наследие Маозари 4

Панежин Евгений
4. Наследие Маозари
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Наследие Маозари 4

Ученик

Губарев Алексей
1. Тай Фун
Фантастика:
фэнтези
5.00
рейтинг книги
Ученик

Начальник милиции. Книга 5

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