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-25thread_make27-38acceptclifdigetiputФункции
thread_makethread_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-26clifdiputigetpthread_cond_waitpthread_cond_signalweb_childЗначения времени центрального процессора, приведенные в табл. 30.1, показывают, что эта версия сервера медленнее рассмотренной в предыдущем разделе (когда каждый поток из пула сам вызывал функцию
acceptЕсли мы рассмотрим гистограмму количества клиентов, обслуживаемых каждым потоком из пула, то окажется, что распределение клиентских запросов по потокам будет таким же, как показано в последнем столбце табл. 30.2. Это означает, что если основной поток вызывает функцию
pthread_cond_signal30.13. Резюме
В этой главе мы рассмотрели 9 различных версий сервера и их работу с одним и тем же веб-клиентом, чтобы сравнить значения времени центрального процессора, затраченного на управление процессом.
0. Последовательный сервер (точка отсчета — управление процессом отсутствует).
1. Параллельный сервер, по одному вызову функции
fork
