UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
Дескрипторы — это просто индексы массива, содержащегося в структуре
procfileforkfilefiledupfileacceptПри запуске программы создается N дочерних процессов, каждый из которых может вызывать функцию
acceptso_timeosocketsocketТакая ситуация иногда называется thundering herd — более или менее дословный перевод будет звучать как «общая побудка», так как все N процессов должны быть выведены из спящего состояния, хотя нужен всего один процесс, и остальные потом снова «засыпают». Тем не менее этот код работает, хотя и имеет побочный эффект — необходимость «будить» слишком много дочерних процессов каждый раз, когда требуется принять (
acceptЭффект наличия слишком большого количества дочерних процессов
В табл. 30.1 (строка 2) указано время (1,8 с), затрачиваемое центральным процессором в случае наличия 15 дочерних процессов, обслуживающих не более 10 клиентов. Мы можем оценить эффект «общей побудки», увеличивая количество дочерних процессов и оставляя то же максимальное значение количества обслуживаемых клиентов (10). Мы не показываем результаты, получаемые при увеличении количества дочерних потоков, потому что они не настолько интересны. Поскольку любое количество дочерних потоков свыше 10 может считаться избыточным, проблема «общей побудки» усугубляется, а затрачиваемое на управление процессами время увеличивается.
Некоторые ядра Unix снабжены функцией, которая выводит из состояния ожидания только один процесс для обработки одного клиентского запроса [107]. Чаще всего она называется wakeup_one.
Распределение клиентских соединений между дочерними процессами
Следующей темой обсуждения является распределение клиентских соединений между свободными дочерними процессами, блокированными в вызове функции
acceptmainlong *cptr, *meter(int); /* для подсчета количества клиентов на одиндочерний процесс */cptr = meter(nchildren); /* перед порождением дочернего процесса */В листинге 30.10 показана функция
meterЛистинг 30.10. Функция meter, которая размещает массив в совместно используемой памяти
//server/meter.c 1 #include "unp.h" 2 #include <sys/mman.h> 3 /* Размещаем массив "nchildren" длинных целых чисел 4 * в совместно используемой области памяти. 5 * Эти числа используются как счетчики количества * клиентов, обслуженных данным дочерним процессом, 6 * см. с. 467-470 книги [110]" 7 */ 8 long* 9 meter(int nchildren)10 {11 int fd;12 long *ptr;13 #ifdef MAP_ANON14 ptr = Mmap(0, nchildren * sizeof(long), PROT_READ | PROT_WRITE,15 MAP_ANON | MAP_SHARED, -1, 0);16 #else17 fd = Open("/dev/zero", O_RDWR, 0);18 ptr = Mmap(0, nchildren * sizeof(long), PROT_READ | PROT_WRITE,19 MAP_SHARED, fd, 0);20 Close(fd);21 #endif22 return (ptr);23 }Мы используем неименованное отображение в память, если оно поддерживается (например, в 4.4BSD), или отображение файла
/dev/zerommapforkЗатем мы модифицируем нашу функцию
child_mainacceptSIGINTВ табл. 30.2 показано распределение нагрузки по дочерним процессам. Когда свободные дочерние процессы блокированы вызовом функции
accept
