Вход/Регистрация
UNIX: разработка сетевых приложений
вернуться

Стивенс Уильям Ричард

Шрифт:

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
.

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

accept
). Причина заключается в том, что рассматриваемая в данном разделе версия использует как взаимное исключение, так и условную переменную, тогда как в предыдущем случае (см. листинг 30.23) применялось только взаимное исключение.

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

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

30.13. Резюме

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

0. Последовательный сервер (точка отсчета — управление процессом отсутствует).

1. Параллельный сервер, по одному вызову функции

fork
для каждого клиента.

2. Предварительное порождение дочерних процессов, каждый из которых вызывает функцию

accept
.

3. Предварительное порождение дочерних процессов с блокировкой файла для защиты функции

accept
.

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

accept
.

5. Предварительное порождение дочерних процессов с передачей дескриптора от родительского процесса дочернему.

6. Параллельный сервер, поочередное создание потоков по мере поступления клиентских запросов.

7. Предварительное порождение потоков с блокировкой взаимного исключения потоками для защиты функции

accept
.

8. Предварительное порождение потоков, основной поток вызывает функцию

accept
.

Резюмируя материал этой главы, можно сделать несколько комментариев.

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

fork
для создания нового дочернего процесса. Этот вариант допускает комбинирование с демоном
inetd
, принимающим все клиентские запросы. Остальные версии применимы в случае загруженных серверов, таких как веб-серверы.

  • Читать дальше
  • 1
  • ...
  • 448
  • 449
  • 450
  • 451
  • 452
  • 453
  • 454
  • 455
  • 456
  • 457
  • 458
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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