UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
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 startingn", (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
Значения времени центрального процессора, приведенные в табл. 30.1, показывают, что эта версия сервера медленнее рассмотренной в предыдущем разделе (когда каждый поток из пула сам вызывал функцию
accept
Если мы рассмотрим гистограмму количества клиентов, обслуживаемых каждым потоком из пула, то окажется, что распределение клиентских запросов по потокам будет таким же, как показано в последнем столбце табл. 30.2. Это означает, что если основной поток вызывает функцию
pthread_cond_signal
30.13. Резюме
В этой главе мы рассмотрели 9 различных версий сервера и их работу с одним и тем же веб-клиентом, чтобы сравнить значения времени центрального процессора, затраченного на управление процессом.
0. Последовательный сервер (точка отсчета — управление процессом отсутствует).
1. Параллельный сервер, по одному вызову функции
fork