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

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

Жанры

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

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

Шрифт:

В листинге 5.11 приведен текст программы, использующей mq_notifу и sigwait.

Листинг 5.11. Использование mq_notify совместно с sigwait

//pxmsg/mqnotifysig4.c

1 #include "unpipc.h"

2 int

3 main(int argc, char **argv)

4 {

5 int signo;

6 mqd_t mqd;

7 void *buff;

8 ssize_t n;

9 sigset_t newmask;

10 struct mq_attr attr;

11 struct sigevent sigev;

12 if (argc != 2)

13 err_quit("usage: mqnotifysig4 <name>");

14 /* открытие очереди, получение атрибутов, выделение буфера */

15 mqd = Mq_open(argv[1], O_RDONLY | O_NONBLOCK);

16 Mq_getattr(mqd, &attr);

17 buff = Malloc(attr.mq_msgsize);

18 Sigemptyset(&newmask);

19 Sigaddset(&newmask, SIGUSR1);

20 Sigprocmask(SIG_BLOCK, &newmask, NULL); /* блокируем SIGUSR1 */

21 /* установка обработчика, включение уведомления */

22 sigev.sigev_notify = SIGEV_SIGNAL;

23 sigev.sigev_signo = SIGUSR1;

24 Mq_notify(mqd, &sigev);

25 for (;;) {

26 Sigwait(&newmask, &signo);

27 if (signo == SIGUSR1) {

28 Mq_notify(mqd, &sigev); /* перерегистрируемся */

29 while ((n = mq_receive(mqd, buff, attr.mq_msgsize, NULL)) >= 0) {

30 printf("read %ld bytes\n", (long) n);

31 }

32 if (errno != EAGAIN)

33 err_sys("mq_receive error");

34 }

35 }

36 exit(0);

37 }

Инициализация набора сигналов и блокировка SIGUSR1

18-20 Инициализируется один набор сигналов, содержащий только SIGUSR1, а затем этот сигнал блокируется sigprocmask.

Ожидание сигнала

26-34 Мы блокируем выполнение программы и ждем прихода сигнала, вызвав sigwait. При получении сигнала SIGUSR1 мы перерегистрируемся на уведомление и считываем все доступные сообщения.

ПРИМЕЧАНИЕ

Функция sigwait часто используется в многопоточных процессах. Действительно, глядя на прототип функции, мы можем заметить, что возвращаемое значение будет 0 или одной из ошибок Еххх, что весьма похоже на функции Pthread. Однако в многопоточном процессе нельзя пользоваться sigprocmask — вместо нее следует вызывать pthread_ sigmask, которая изменяет маску сигналов только для вызвавшего ее потока. Аргументы pthread_sigmask совпадают с аргументами sigprocmask.

Существуют два варианта функции sigwait: sigwaitinfo возвращает структуру siginfo_t (которая будет определена в следующем разделе) и предназначена для использования с надежными сигналами; функция sigtimedwait также возвращает структуру siginfo_t и позволяет вызывающему процессу установить ограничение по времени на ожидание.

Большая часть книг о многопоточном программировании, таких как [3], рекомендуют пользоваться sigwait для обработки всех сигналов в многопоточном процессе и не использовать асинхронные обработчики. 

Пример: очереди сообщений Posix и функция select

Дескриптор очереди сообщений (переменная типа mqd_t) не является «обычным» дескриптором и не может использоваться с функциями select и poll (глава 6 [24]). Тем не менее их можно использовать вместе с каналом и функцией mq_notify. (Аналогичный метод применен в разделе 6.9 для очередей System V, где создается дочерний процесс и канал связи.) Прежде всего обратите внимание, что, согласно табл. 5.1, функция write принадлежит к группе async-signal-safe, поэтому она может вызываться из обработчика сигналов. Программа приведена в листинге 5.12.

Листинг 5.12. Использование уведомления с помощью сигнала и канала

//pxmsg/mqnotifysig5.c

1 #include "unpipc.h"

2 int pipefd[2];

3 static void sig_usr1(int);

4 int

5 main(int argc, char **argv)

6 {

7 int nfds;

8 char c;

9 fd_set rset;

10 mqd_t mqd;

11 void *buff;

12 ssize_t n;

13 struct mq_attr attr;

14 struct sigevent sigev;

15 if (argc != 2)

16 err_quit("usage: mqnotifysig5 <name>");

17 /* открытие очереди, получение атрибутов, выделение буфера */

18 mqd = Mq_open(argv[1], O_RDONLY | O_NONBLOCK);

19 Mq_getattr(mqd, &attr);

20 buff = Malloc(attr.mq_msgsize);

21 Pipe(pipefd);

22 /* установка обработчика, включение уведомления */

23 Signal(SIGUSR1, sig_usr1);

24 sigev.sigev_notify = SIGEV_SIGNAL;

25 sigev.sigev_signo = SIGUSR1;

26 Mq_notify(mqd, &sigev);

27 FD_ZERO(&rset);

28 for (;;) {

29 FD_SET(pipefd[0], &rset);

30 nfds = Select(pipefd[0] + 1, &rset, NULL, NULL, NULL);

31 if (FD_ISSET(pipefd[0], &rset)) {

32 Read(pipefd[0], &c, 1);

33 Mq_notify(mqd, &sigev); /* перерегистрируемся */

34 while ((n = mq_receive(mqd, buff, attr.mq_msgsize, NULL)) >= 0) {

35 printf("read %ld bytes\n", (long) n);

36 }

37 if (errno != EAGAIN)

38 err_sys("mq_receive error");

39 }

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

Газлайтер. Том 40

Володин Григорий Григорьевич
40. История Телепата
Фантастика:
альтернативная история
аниме
попаданцы
5.00
рейтинг книги
Газлайтер. Том 40

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

INDIGO
15. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 9. Часть 2

Дважды одаренный. Том IV

Тарс Элиан
4. Дважды одаренный
Фантастика:
городское фэнтези
альтернативная история
аниме
7.00
рейтинг книги
Дважды одаренный. Том IV

Точка Бифуркации

Смит Дейлор
1. ТБ
Фантастика:
боевая фантастика
7.33
рейтинг книги
Точка Бифуркации

Студент из прошлого тысячелетия

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

Иной. Том 1. Школа на краю пустыни

Amazerak
1. Иной в голове
Фантастика:
боевая фантастика
рпг
аниме
5.75
рейтинг книги
Иной. Том 1. Школа на краю пустыни

Белые погоны

Лисина Александра
3. Гибрид
Фантастика:
фэнтези
попаданцы
технофэнтези
аниме
5.00
рейтинг книги
Белые погоны

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

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

"Дальние горизонты. Дух". Компиляция. Книги 1-25

Усманов Хайдарали
Собрание сочинений
Фантастика:
фэнтези
боевая фантастика
попаданцы
5.00
рейтинг книги
Дальние горизонты. Дух. Компиляция. Книги 1-25

Ожерелье Странника

Хаггард Генри Райдер
Приключения:
исторические приключения
7.50
рейтинг книги
Ожерелье Странника

Агенты ВКС

Вайс Александр
3. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
5.00
рейтинг книги
Агенты ВКС

Воронцов. Перезагрузка. Книга 2

Тарасов Ник
2. Воронцов. Перезагрузка
Фантастика:
попаданцы
альтернативная история
фэнтези
5.00
рейтинг книги
Воронцов. Перезагрузка. Книга 2

Роза ветров

Кас Маркус
6. Артефактор
Фантастика:
городское фэнтези
аниме
фэнтези
5.00
рейтинг книги
Роза ветров

Путь

Yagger Егор
Фантастика:
космическая фантастика
4.25
рейтинг книги
Путь