Чтение онлайн

на главную - закладки

Жанры

UNIX: разработка сетевых приложений
Шрифт:

Функция

child_make
остается такой же, как в листинге 30.8. Единственным изменением функции
child_main
(см. листинг 30.9) является блокирование перед вызовом функции
accept
и снятие блокировки после завершения этой функции:

for (;;) {

clilen = addrlen;

+ my_lock_wait;

connfd = Accept(listenfd, cliaddr, &clilen);

+ my_lock_release;

web_child(connfd); /* обработка запроса */

Close(connfd);

}

В

листинге 30.12 показана наша функция
my_lock_init
, в которой используется блокировка файла согласно стандарту POSIX.

Листинг 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-12
Вызывающий процесс задает шаблон для имени файла в качестве аргумента функции
my_lock_init
, и функция
mkstemp
на основе этого шаблона создает уникальное имя файла. Затем создается файл с этим именем и сразу же вызывается функция
unlink
, в результате чего имя файла удаляется из каталога. Если в программе впоследствии произойдет сбой, то файл исчезнет безвозвратно. Но пока он остается открытым в одном или нескольких процессах (иными словами, пока счетчик ссылок для этого файла больше нуля), сам файл не будет удален. (Отметим, что между удалением имени файла из каталога и закрытием открытого файла существует фундаментальная разница.)

13-20
Инициализируются две структуры flock: одна для блокирования файла, другая для снятия блокировки. Блокируемый диапазон начинается с нуля (
l_whence =SEEK_SET, l_start=0
). Значение
l_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.12.

Листинг 30.13. Функции my_lock_wait (установление блокировки файла) и my_lock_release (снятие блокировки файла)

//server/lock_fcntl.c

23 void

24 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 else

31 errsys("fcntl error for my_lock_wait");

32 }

33 }

34 void

35 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
. Сравнивая строки 2 и 3 в табл. 30.1 (результаты для серверов Digital Unix и BSD/OS), мы видим, что такой тип блокировки увеличивает время, затрачиваемое центральным процессором на узле сервера.

ПРИМЕЧАНИЕ

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

Эффект наличия слишком большого количества дочерних процессов

Мы можем проверить, возникает ли в данной версии сервера эффект «общей побудки», рассмотренный в предыдущем разделе. Как и раньше, время работы ухудшается пропорционально числу избыточных дочерних процессов.

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

Особое назначение

Тесленок Кирилл Геннадьевич
2. Гарем вне закона
Фантастика:
фэнтези
6.89
рейтинг книги
Особое назначение

Её (мой) ребенок

Рам Янка
Любовные романы:
современные любовные романы
6.91
рейтинг книги
Её (мой) ребенок

Я Гордый часть 2

Машуков Тимур
2. Стальные яйца
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я Гордый часть 2

Адепт. Том второй. Каникулы

Бубела Олег Николаевич
7. Совсем не герой
Фантастика:
фэнтези
попаданцы
9.05
рейтинг книги
Адепт. Том второй. Каникулы

Императорский отбор

Свободина Виктория
Фантастика:
фэнтези
8.56
рейтинг книги
Императорский отбор

Законы Рода. Том 6

Flow Ascold
6. Граф Берестьев
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Законы Рода. Том 6

Начальник милиции. Книга 3

Дамиров Рафаэль
3. Начальник милиции
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Начальник милиции. Книга 3

Огненный князь 3

Машуков Тимур
3. Багряный восход
Фантастика:
фэнтези
боевая фантастика
попаданцы
5.00
рейтинг книги
Огненный князь 3

Восход. Солнцев. Книга VI

Скабер Артемий
6. Голос Бога
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Восход. Солнцев. Книга VI

Страж. Тетралогия

Пехов Алексей Юрьевич
Страж
Фантастика:
фэнтези
9.11
рейтинг книги
Страж. Тетралогия

Мастер 7

Чащин Валерий
7. Мастер
Фантастика:
фэнтези
боевая фантастика
попаданцы
технофэнтези
аниме
5.00
рейтинг книги
Мастер 7

Волк 5: Лихие 90-е

Киров Никита
5. Волков
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Волк 5: Лихие 90-е

Сломанная кукла

Рам Янка
5. Серьёзные мальчики в форме
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Сломанная кукла

Идеальный мир для Лекаря 18

Сапфир Олег
18. Лекарь
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 18