UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
Листинг 30.12. Функция my_lock_init: блокировка файла
//server/lock_fcntl.c 1 #include "unp.h" 2 static struct flock lock_it, unlock_it; 3 static int lock_fd = -1; 4 /* fcntl() не выполнится, если не будет вызвана функция my_lock_init() */ 5 void 6 my_lock_init(char *pathname) 7 { 8 char lock_file[1024]; 9 /* копируем строку вызывающего процесса на случай, если это константа */10 strncpy(lock_file, pathname, sizeof(lock_file));11 lock_fd = Mkstemp(lock_file);12 Unlink(lock_file); /* но lock_fd остается открытым */13 lock_it.l_type = F_WRLCK;14 lock_it.l_whence = SEEK_SET;15 lock_it.l_start = 0;16 lock_it.l_len = 0;17 unlock_it.l_type = F_UNLCK;18 unlock_it.l_whence = SEEK_SET;19 unlock_it.l_start = 0;20 unlock_it.l_len = 0;21 }9-12my_lock_initmkstempunlink13-20l_whence =SEEK_SET, l_start=0l_lenСначала автор инициализировал эти структуры при объявлении:
static struct flock lock_it = { F_WRLCK, 0, 0, 0, 0 };static struct flock unlock_it = { F_UNLCK, 0, 0, 0, 0 };но тут возникли две проблемы: у нас нет гарантии, что константа SEEK_SET равна нулю, но, что более важно, стандарт POSIX не регламентирует порядок расположения полей этой структуры. POSIX гарантирует только то, что требуемые поля присутствуют в структуре. POSIX не гарантирует какого-либо порядка следования полей структуры, а также допускает наличие в ней полей, не относящихся к стандарту POSIX. Поэтому когда требуется инициализировать эту структуру (если только не нужно инициализировать все поля нулями), это приходится делать через фактический код С, а не с помощью инициализатора при объявлении структуры.
Исключением из этого правила является ситуация, когда инициализатор структуры обеспечивается реализацией. Например, при инициализации взаимного исключения в POSIX в главе 26 мы писали:
pthread_mutex_t mlock = PTHREAD_MUTEX_INITIALIZER;Тип данных pthread_mutex_t — это некая структура, но инициализатор предоставляется реализацией и может быть различным для разных реализаций.
В листинге 30.13 показаны две функции, которые устанавливают и снимают блокировку с файла. Они представляют собой вызовы функции
fcntlЛистинг 30.13. Функции my_lock_wait (установление блокировки файла) и my_lock_release (снятие блокировки файла)
//server/lock_fcntl.c23 void24 my_lock_wait()25 {26 int rc;27 while ((rc = fcntl(lock_ld, F_SETLKW, &lock_it)) < 0 {28 if (errno == EINTR)29 continue;30 else31 errsys("fcntl error for my_lock_wait");32 }33 }34 void35 my_lock_release()36 {37 if (fcntl(lock_fd, F_SETLKW, &unlock_it)) < 0)38 errsys("fcntl error for my_lock_release");39 }Новая версия нашего сервера с предварительным порождением процессов работает теперь под SVR4, гарантируя, что в данный момент времени только один дочерний процесс блокирован в вызове функции
acceptВеб-сервер Apache (http://www.apache.org) использует технологию предварительного порождения процессов, причем если позволяет реализация, все дочерние процессы блокируются в вызове функции accept, иначе используется блокировка файла для защиты вызова accept.
Эффект наличия слишком большого количества дочерних процессов
Мы можем проверить, возникает ли в данной версии сервера эффект «общей побудки», рассмотренный в предыдущем разделе. Как и раньше, время работы ухудшается пропорционально числу избыточных дочерних процессов.
Распределение клиентских соединений между дочерними процессами
Используя функцию, показанную в листинге 30.10, мы можем исследовать распределение клиентских запросов между свободными дочерними процессами. Результат показан в табл. 30.2. Операционная система распределяет блокировки файла равномерно между ожидающими процессами, и такое поведение характерно для нескольких протестированных нами систем.
