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

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

Жанры

UNIX: взаимодействие процессов

Стивенс Уильям Ричард

Шрифт:
Установка обработчика сигнала для SIGCHLD

10 Поскольку для каждого клиента порождается отдельный процесс, нужно позаботиться о процессах-зомби. В разделах 5.9 и 5.10 [24] об этом говорится подробно. Здесь мы просто установим обработчик для сигнала SIGCHLD, и наша функция sig_chld (листинг 6.18) будет вызываться при завершении работы дочернего процесса.

12-18 Породивший процесс сервера блокируется в вызове mesg_recv, ожидая появления сообщения от очередного клиента.

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

Функция-обработчик для SIGCHLD приведена в листинге 6.18. Она скопирована с листинга 5.11 [24].

Листинг 6.18. Обработчик сигнала SIGCHLD, вызывающий waitpid

//svmsgmpxnq/sigchldwaitpid.с

1 #include "unpipc.h"

2 void

3 sig_chld(int signo)

4 {

5 pid_t pid;

6 int stat;

7 while ((pid = waitpid(-1, &stat, WNOHANG)) > 0);

8 return;

9 }

Каждый раз при вызове обработчика происходит циклический вызов waitpid для получения статуса завершения работы всех дочерних процессов, которые могли завершить работу. Затем происходит возврат из обработчика сигнала. При этом может возникнуть проблема, поскольку родительский процесс проводит большую часть времени в заблокированном состоянии (при вызове mesg_recv, листинг 6.9). При возвращении из обработчика этот вызов msgrcv прерывается. Функция возвращает ошибку с кодом EINTR, как рассказывается в разделе 5.9 [24]. 

Нам нужно обработать такой возврат из вызванной функции, поэтому мы пишем новую функцию-обертку Mesg_recv, приведенную в листинге 6.20. Эта программа допускает возвращение ошибки с кодом EINTR функцией mesg_recv (которая просто вызывает msgrcv), и, если это происходит, мы просто еще раз вызываем mesg_recv.

Листинг 6.19. Функция server

//svmsgmpxnq/server.c

1 #include "mesg.h"

2 void

3 server(int readid, int writeid)

4 {

5 FILE *fp;

6 char *ptr;

7 ssize_t n;

8 struct mymesg mesg;

9 void sig_chld(int);

10 Signal(SIGCHLD, sig_chld);

11 for (;;) {

12 /* считывание имени файла из очереди */

13 mesg.mesg_type = 1;

14 if ((n = Mesg_recv(readid, &mesg)) == 0) {

15 err_msg("pathname missing");

16 continue;

17 }

18 mesg.mesg_data[n] = 40'; /* имя файла */

19 if ((ptr = strchr(mesg.mesg_data, ' ')) = NULL) {

20 err_msg("bogus request: %s", mesg.mesg_data);

21 continue;

22 }

23 *ptr++ = 0; /* ptr = имя файла */

24 writeid = atoi(mesg.mesg_data);

25 if (Fork == 0) { /* дочерний процесс */

26 if ((fp = fopen(ptr, "r")) == NULL) {

27 /* ошибка: нужно сообщить клиенту */

28 snprintf(mesg.mesg_data + n, sizeof(mesg.mesg_data) – n,

29 ": can't open, %s\n", strerror(errno));

30 mesg.mesg_len = strlen(ptr);

31 memmove(mesg.mesg_data, ptr, mesg.mesg_len);

32 Mesg_send(writeid, &mesg);

33 } else {

34 /* файл открыт, копируем клиенту */

35 while (Fgets(mesg.mesg_data, MAXMESGDATA, fp) != NULL) {

36 mesg.mesg_len = strlen(mesg.mesg_data);

37 Mesg_send(writeid, &mesg);

38 }

39 Fclose(fp);

40 }

41 /* отправка сообщения нулевой длины, указывающего конец файла */

42 mesg.mesg_len = 0;

43 Mesg_send(writeid, &mesg);

44 exit(0); /* завершение дочернего процесса */

45 }

46 /* родительский процесс просто зациклен */

47 }

48 }

Листинг 6.20. Функция-обертка Mesg_recv, обрабатывающая прерванный системный вызов

//svmsgmpxnq/mesg_recv.с

10 ssize_t

11 Mesg_recv(int id, struct mymesg *mptr)

12 {

13 ssize_t n;

14 do {

15 n = mesg_recv(id, mptr);

16 } while (n == –1 && errno == EINTR);

17 if (n == –1)

18 err_sys("mesg_recv error");

19 return(n);

20 }

6.9. Использование select и poll с очередями сообщений

Одним из недостатков очередей сообщений System V является то, что они идентифицируются не дескрипторами, а идентификаторами. Поэтому с ними нельзя использовать функции select и poll (глава 6 [24]).

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

Искушение генерала драконов

Лунёва Мария
2. Генералы драконов
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Искушение генерала драконов

На границе империй. Том 10. Часть 3

INDIGO
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 3

Последний Паладин. Том 9

Саваровский Роман
9. Путь Паладина
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Последний Паладин. Том 9

Низший - Инфериор. Компиляция. Книги 1-19

Михайлов Дем Алексеевич
Фантастика 2023. Компиляция
Фантастика:
боевая фантастика
5.00
рейтинг книги
Низший - Инфериор. Компиляция. Книги 1-19

Камень. Книга пятая

Минин Станислав
5. Камень
Фантастика:
боевая фантастика
6.43
рейтинг книги
Камень. Книга пятая

Ученик. Книга 4

Первухин Андрей Евгеньевич
4. Ученик
Фантастика:
фэнтези
5.67
рейтинг книги
Ученик. Книга 4

Пламенев. Книга 3-7

Карелин Сергей Витальевич
Пламенев
Фантастика:
аниме
уся
фэнтези
сянься
5.00
рейтинг книги
Пламенев. Книга 3-7

Хозяин Стужи 5

Петров Максим Николаевич
5. Злой Лед
Фантастика:
аниме
фэнтези
попаданцы
6.60
рейтинг книги
Хозяин Стужи 5

Группа крови на рукаве

Вязовский Алексей
1. ГК
Фантастика:
боевая фантастика
попаданцы
альтернативная история
6.40
рейтинг книги
Группа крови на рукаве

Гримуар темного лорда III

Грехов Тимофей
3. Гримуар темного лорда
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Гримуар темного лорда III

Запасная дочь

Зика Натаэль
Фантастика:
фэнтези
6.40
рейтинг книги
Запасная дочь

Черный Маг Императора 20

Герда Александр
20. Черный маг императора
Фантастика:
юмористическое фэнтези
аниме
сказочная фантастика
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Черный Маг Императора 20

Князь Серединного мира

Земляной Андрей Борисович
4. Страж
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Князь Серединного мира

Адвокат империи

Карелин Сергей Витальевич
1. Адвокат империи
Фантастика:
городское фэнтези
попаданцы
фэнтези
5.75
рейтинг книги
Адвокат империи