UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
linux % <b>udpserv01</b>
cntread[0] = 2
cntread[1] = 21838
cntread[2] = 12
cntread[3] = 1
cntread[4] = 0
cntread[5] = 1
cntread[6] = 0
cntread[7] = 0
cntread[8] = 0
Большую часть времени обработчик сигналов читает только одну дейтаграмму, но бывает, что готово больше одной дейтаграммы. Ненулевое значение счетчика
cntread[0]
cntread[0]>0
25.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, когда процессу требуется, чтобы некое действие было выполнено каким-либо другим объектом, он порождает дочерний процесс, используя функцию
fork
accept
fork
Хотя эта концепция с успехом использовалась на протяжении многих лет, с функцией
fork
■ Стоимость функции
fork
fork
■ Для передачи данных между родительским и дочерним процессами после вызова функции
fork
fork
Обе проблемы могут быть разрешены путем использования программных потоков (threads). Программные потоки иногда называются облегченными процессами (lightweight processes), так как поток проще, чем процесс. В частности, создание потока требует в 10–100 раз меньше времени, чем создание процесса.
Все потоки одного процесса совместно используют его глобальные переменные, поэтому им легко обмениваться информацией, но это приводит к необходимости синхронизации.
Однако общими становятся не только глобальные переменные. Все потоки одного процесса разделяют:
■ инструкции процесса;
■ большую часть данных;
■ открытые файлы (например, дескрипторы);
■ обработчики сигналов и вообще настройки для работы с сигналами (действие сигнала);
■ текущий рабочий каталог;
■ идентификаторы пользователя и группы пользователей.
У каждого потока имеются собственные:
■ идентификатор потока;
■ набор регистров, включая счетчик команд и указатель стека;
■ стек (для локальных переменных и адресов возврата);
■ переменная
errno
■ маска сигналов;
■ приоритет.
Как сказано в разделе 11.18, можно рассматривать обработчик сигнала как некую разновидность потока. В традиционной модели Unix у нас имеется основной поток выполнения и обработчик сигнала (другой поток). Если в основном потоке в момент возникновения сигнала происходит корректировка связного списка и обработчик сигнала также пытается изменить связный список, обычно начинается путаница. Основной поток и обработчик сигнала совместно используют одни и те же глобальные переменные, но у каждого из них имеется свой собственный стек.
В этой книге мы рассматриваем потоки POSIX, которые также называются Pthreads (POSIX threads). Они были стандартизованы в 1995 году как часть POSIX.1c и будут поддерживаться большинством версий Unix. Мы увидим, что все названия функций Pthreads начинаются с символов
pthread_