UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
linux % <b>udpserv01</b>cntread[0] = 2cntread[1] = 21838cntread[2] = 12cntread[3] = 1cntread[4] = 0cntread[5] = 1cntread[6] = 0cntread[7] = 0cntread[8] = 0Большую часть времени обработчик сигналов читает только одну дейтаграмму, но бывает, что готово больше одной дейтаграммы. Ненулевое значение счетчика
cntread[0]cntread[0]>025.4. Резюме
При управляемом сигналом вводе-выводе ядро уведомляет процесс сигналом
SIGIO■ Для присоединенного TCP-сокета существует множество ситуаций, которые вызывают такое уведомление, что делает эту возможность практически бесполезной.
■ Для прослушиваемого TCP-сокета уведомление приходит процессу только в случае готовности принятия нового соединения.
■ Для UDP такое уведомление означает, что либо пришла дейтаграмма, либо произошла асинхронная ошибка: в обоих случаях вызывается
recvfromС помощью метода, аналогичного применяемому для сервера NTP, был изменен эхо-сервер UDP для работы с вводом-выводом, управляемым сигналом: мы стремимся выполнить чтение дейтаграммы как можно быстрее после ее прибытия, чтобы получить точную отметку времени прибытия и поставить дейтаграмму в очередь для дальнейшей обработки.
Упражнения
1. Далее приведен альтернативный вариант цикла, рассмотренного в листинге 25.2:
for (;;) { Sigprocmask(SIG_BLOCK, &newmask, &oldmask); while (nqueue == 0) sigsuspend(&zeromask); /* ожидание дейтаграммы для обработки */ nqueue--; /* разблокирование SIGIO */ Sigprocmask(SIG_SETMASK, &oldmask, NULL); Sendto(sockfd, dg[iget].dg_data, dg[iget].dg_len, 0, dg[iget].dg_sa, dg[iget].dg_salen); if (++iget >= QSIZE) iget = 0;}Верна ли такая модификация?
Глава 26
Программные потоки
26.1. Введение
Согласно традиционной модели Unix, когда процессу требуется, чтобы некое действие было выполнено каким-либо другим объектом, он порождает дочерний процесс, используя функцию
forkacceptforkХотя эта концепция с успехом использовалась на протяжении многих лет, с функцией
fork■ Стоимость функции
forkfork■ Для передачи данных между родительским и дочерним процессами после вызова функции
forkforkОбе проблемы могут быть разрешены путем использования программных потоков (threads). Программные потоки иногда называются облегченными процессами (lightweight processes), так как поток проще, чем процесс. В частности, создание потока требует в 10–100 раз меньше времени, чем создание процесса.
Все потоки одного процесса совместно используют его глобальные переменные, поэтому им легко обмениваться информацией, но это приводит к необходимости синхронизации.
Однако общими становятся не только глобальные переменные. Все потоки одного процесса разделяют:
■ инструкции процесса;
■ большую часть данных;
■ открытые файлы (например, дескрипторы);
■ обработчики сигналов и вообще настройки для работы с сигналами (действие сигнала);
■ текущий рабочий каталог;
■ идентификаторы пользователя и группы пользователей.
У каждого потока имеются собственные:
■ идентификатор потока;
■ набор регистров, включая счетчик команд и указатель стека;
■ стек (для локальных переменных и адресов возврата);
■ переменная
errno■ маска сигналов;
■ приоритет.
Как сказано в разделе 11.18, можно рассматривать обработчик сигнала как некую разновидность потока. В традиционной модели Unix у нас имеется основной поток выполнения и обработчик сигнала (другой поток). Если в основном потоке в момент возникновения сигнала происходит корректировка связного списка и обработчик сигнала также пытается изменить связный список, обычно начинается путаница. Основной поток и обработчик сигнала совместно используют одни и те же глобальные переменные, но у каждого из них имеется свой собственный стек.
В этой книге мы рассматриваем потоки POSIX, которые также называются Pthreads (POSIX threads). Они были стандартизованы в 1995 году как часть POSIX.1c и будут поддерживаться большинством версий Unix. Мы увидим, что все названия функций Pthreads начинаются с символов
pthread_
