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

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

Жанры

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

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

Шрифт:

Досрочное завершение сервера

Если клиент блокируется в вызове door_call, ожидая получения результатов, ему нужно каким-то образом получить уведомление о завершении потока сервера по какой-либо причине. Посмотрим, что происходит в этом случае, прервав работу сервера вызовом pthread_exit. Это приведет к завершению потока сервера (а не всего процесса). В листинге 15.20 приведен текст процедуры сервера.

Листинг 15.20. Процедура сервера, завершающая работу сразу после запуска

//doors/serverintr1.c

1 #include "unpipc.h"

2 void

3 servproc(void *cookie, char *dataptr, size_t datasize,

4 door_desc_t *descptr, size_t ndesc)

5 {

6 long arg, result;

7 pthread_exit(NULL); /* посмотрим, что произойдет с клиентом */

8 arg = *((long*)dataptr);

9 result = arg * arg;

10 Door_return((char*)&result, sizeof(result), NULL, 0);

11 }

Оставшаяся часть сервера не претерпевает изменений по сравнению с листингом 15.2, а программу-клиент мы берем из листинга 15.1.

Запустив клиент, мы увидим, что вызов door_call возвращает ошибку EINTR, если процедура сервера завершается досрочно:

solaris % clientintr1 /tmp/door1 11

door_call error: Interrupted system call

Непрерываемость системного вызова door_call

Документация на door_call предупреждает, что эта функция не предполагает возможности перезапуска (библиотечная функция door_call делает системный вызов с тем же именем). Мы можем убедиться в этом, изменив процедуру сервера таким образом, чтобы она делала паузу в 6 секунд перед возвращением, что показано в листинге 15.21.

Листинг 15.21. Процедура сервера делает паузу в 6 секунд

//doors/serverintr2.с

1 #include "unpipc.h"

2 void

3 servproc(void *cookie, char *dataptr, size_t datasize,

4 door_desc_t *descptr, size_t ndesc)

5 {

6 long arg, result;

7 sleep(6); /* клиент получает сигнал SIGCHLD */

8 arg = *((long*)dataptr);

9 result = arg * arg;

10 Door_return((char*)&result, sizeof(result), NULL, 0);

11 }

Изменим теперь клиент из листинга 15.2: установим обработчик сигнала SIGCHLD, добавив порождение процесса и завершение порожденного процесса через 2 секунды. Таким образом, через 2 секунды после вызова door_call дочерний процесс завершит работу, а родительский перехватит сигнал SIGCHLD и произойдет возврат из обработчика сигнала, прерывающий системный вызов door_call. Текст программы-клиента показан в листинге 15.22.

Листинг 15.22. Клиент, перехватывающий сигнал SIGCHLD

//doors/clientintr2.c

1 #include "unpipc.h"

2 void

3 sig_chld(int signo)

4 {

5 return; /* просто прерываем door_call */

6 }

7 int

8 main(int argc, char **argv)

9 {

10 int fd;

11 long ival, oval;

12 door_arg_t arg;

13 if (argc != 3)

14 err_quit("usage: clientintr2 <server-pathname> <integer-value>");

15 fd = Open(argv[1], O_RDWR); /* открываем дверь */

16 /* подготовка аргументов и указателя на результат */

17 ival = atol(argv[2]);

18 arg.data_ptr = (char*)&ival; /* аргументы */

19 arg.data_size = sizeof(long); /* размер аргументов */

20 arg.desc_ptr = NULL;

21 arg.desc_num = 0;

22 arg.rbuf = (char*)&oval; /* данные */

23 arg.rsize = sizeof(long); /* размер данных */

24 Signal(SIGCHLD, sig_chld);

25 if (Fork == 0) {

26 sleep(2); /* дочерний процесс */

27 exit(0); /* отправка SIGCHLD */

28 }

29 /* вызов процедуры сервера и вывод результата */

30 Door_call(fd, &arg);

31 printf(result: %ld\n", oval);

32 exit(0);

33 }

Клиенту будет возвращена та же ошибка, что и при досрочном завершении сервера — EINTR:

solaris % clientintr2 /tmp/door2 22

door_call error: interrupted system call

Поэтому нужно блокировать все сигналы, которые могут прервать вызов door_call.

Идемпотентные и неидемпотентные процедуры

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

Кодекс Охотника. Книга XXXVIII

Винокуров Юрий
38. Кодекс Охотника
Фантастика:
фэнтези
боевая фантастика
попаданцы
юмористическое фэнтези
5.00
рейтинг книги
Кодекс Охотника. Книга XXXVIII

Т. 03 Гражданин Галактики

Хайнлайн Роберт Энсон
3. Отцы-основатели. Весь Хайнлайн
Фантастика:
научная фантастика
7.00
рейтинг книги
Т. 03 Гражданин Галактики

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

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

Кадет Морозов

Шелег Дмитрий Витальевич
4. Живой лёд
Фантастика:
боевая фантастика
5.72
рейтинг книги
Кадет Морозов

Андер Арес

Грехов Тимофей
1. Андер Арес
Фантастика:
рпг
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Андер Арес

Кукловод

Злобин Михаил
2. О чем молчат могилы
Фантастика:
боевая фантастика
8.50
рейтинг книги
Кукловод

Кодекс Крови. Книга IХ

Борзых М.
9. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга IХ

Кодекс Крови. Книга V

Борзых М.
5. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга V

Враг из прошлого тысячелетия

Еслер Андрей
4. Соприкосновение миров
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Враг из прошлого тысячелетия

Кодекс Охотника. Книга XIX

Винокуров Юрий
19. Кодекс Охотника
Фантастика:
фэнтези
5.00
рейтинг книги
Кодекс Охотника. Книга XIX

Я еще не царь

Дрейк Сириус
25. Дорогой барон!
Фантастика:
юмористическое фэнтези
аниме
попаданцы
5.00
рейтинг книги
Я еще не царь

Мл. сержант. Назад в СССР. Книга 3

Гаусс Максим
3. Второй шанс
Фантастика:
альтернативная история
6.40
рейтинг книги
Мл. сержант. Назад в СССР. Книга 3

Неведомые дороги (сборник)

Кунц Дин Рей
Фантастика:
ужасы и мистика
8.00
рейтинг книги
Неведомые дороги (сборник)

Статьи

Переслегин Сергей Борисович
Документальная литература:
публицистика
5.00
рейтинг книги
Статьи