UNIX: разработка сетевых приложений
Шрифт:
6 int
7 main(int argc, char **argv)
8 {
9 int i, listenfd, connfd;
10 void sig_int(int), thread_make(int);
11 socklen_t addrlen, clilen;
12 struct sockaddr *cliaddr;
13 if (argc == 3)
14 listenfd = Tcp_listen(NULL, argv[1], &addrlen);
15 else if (argc == 4)
16 listenfd = Tcp_listen(argv[1], argv[2], &addrlen);
17 else
18 err_quit("usage: serv08 [ <host> ] <port#> <#threads>");
19 cliaddr = Malloc(addrlen);
20 nthreads = atoi(argv[argc - 1]);
21 tptr = Calloc(nthreads, sizeof(Thread));
22 iget = iput = 0;
23 /*
создание всех потоков */
24 for (i = 0; i < nthreads; i++)
25 thread_make(i); /* завершается только основной поток */
26 Signal(SIGINT, sig_int);
27 for (;;) {
28 clilen = addrlen;
29 connfd = Accept(listenfd, cliaddr, &clilen);
30 Pthread_mutex_lock(&clifd_mutex);
31 clifd[iput] = connfd;
32 if (++iput == MAXNCLI)
33 iput = 0;
34 if (iput == iget)
35 err_quit("iput = iget = %d", iput);
36 Pthread_cond_signal(&clifd_cond);
37 Pthread_mutex_unlock(&clifd_mutex);
38 }
39 }
Создание пула потоков
23-25
Функция thread_make
создает все потоки. Ожидание прихода клиентского соединения
27-38
Основной поток блокируется в вызове функции accept
, ожидая появления нового соединения. При появлении этого соединения дескриптор присоединенного сокета записывается в следующий элемент массива clifd
после блокирования взаимного исключения. Мы также следим, чтобы индекс iget
не совпал со значением индекса iput
, что укажет на недостаточно большой размер массива. Условная переменная сигнализирует о прибытии нового запроса, и взаимное исключение разблокируется, позволяя одному из потоков пула обслужить прибывший запрос. Функции
thread_make
и thread_main
показаны
Листинг 30.26. Функции thread_make и thread_main
//server/pthread08.c
1 #include "unpthread.h"
2 #include "pthread08.h"
3 void
4 thread_make(int i)
5 {
6 void *thread_main(void*);
7 Pthread_create(&tptr[i].thread_tid, NULL, &thread_main, (void*)i);
8 return; /* завершается основной поток */
9 }
10 void*
11 thread_main(void *arg)
12 {
13 int connfd;
14 void web_child(int);
15 printf("thread %d starting\n", (int)arg);
16 for (;;) {
17 Pthread_mutex_lock(&clifd_mutex);
18 while (iget == iput)
19 Pthread_cond_wait(&clifd_cond, &clifd_mutex);
20 connfd = clifd[iget]; /* присоединенный сокет, который требуется
обслужить */
21 if (++iget == MAXNCLI)
22 iget = 0;
23 Pthread_mutex_unlock(&clifd_mutex);
24 tptr[(int)arg].thread_count++;
25 web_child(connfd); /* обработка запроса */
26 Close(connfd);
27 }
28 }
Ожидание присоединенного сокета, который требует обслуживания
17-26
Каждый поток из пула пытается блокировать взаимное исключение, блокирующее доступ к массиву clifd
. Если после того, как взаимное исключение заблокировано, оказывается, что индексы iput
и iget
равны, то вызывается функция pthread_cond_wait
, и поток переходит в состояние ожидания, так как ему пока нечего делать. После прибытия очередного клиентского запроса основной поток вызывает функцию pthread_cond_signal
, выводя тем самым из состояния ожидания поток, заблокировавший взаимное исключение. Когда этот поток получает соединение, он вызывает функцию web_child
.
Поделиться:
Популярные книги
Империя отходит от края
2. Империя у края
Фантастика:
альтернативная история
5.00
рейтинг книги
Газлайтер. Том 8
8. История Телепата
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 8
8. Меркурий
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Нищенка в элитной академии
4. Академия юных сердец
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Последняя Арена
1. Последняя Арена
Фантастика:
боевая фантастика
постапокалипсис
рпг
6.20
рейтинг книги
Найденыш
2. Светлая Тьма
Фантастика:
юмористическое фэнтези
городское фэнтези
аниме
5.00
рейтинг книги
Энфис 7
7. Эрра
Фантастика:
героическая фантастика
рпг
аниме
5.00
рейтинг книги
Мимик!
1. Сбой Системы!
Фантастика:
боевая фантастика
5.40
рейтинг книги
Виконт. Книга 2. Обретение силы
2. Псевдоним `Испанец`
Фантастика:
боевая фантастика
попаданцы
рпг
7.10
рейтинг книги
Повелитель механического легиона. Том I
1. Повелитель механического легиона
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Волк: лихие 90-е
1. Волков
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Смерть может танцевать 2
2. Безликий
Фантастика:
героическая фантастика
альтернативная история
6.14
рейтинг книги
"Искажающие реальность" Компиляция. Книги 1-14
Искажающие реальность
Фантастика:
боевая фантастика
космическая фантастика
киберпанк
рпг
5.00
рейтинг книги
Идеальный мир для Лекаря 15
15. Лекарь
Фантастика:
боевая фантастика
юмористическая фантастика
аниме
5.00