Открытие очереди сообщений
15-18 Мы открываем очередь сообщений, получаем ее атрибуты и выделяем буфер считывания.
Листинг 5.9. Обработчик сигнала устанавливает флаг для главного потока (неправильная версия)
//pxmsg/mqnotifysig2.c
1 #include "unpipc.h"
2 volatile sig_atomic_t mqflag; /* ненулевое значение устанавливается обработчиком */
3 static void sig_usrl(int);
4 int
5 main(int argc, char **argv)
6 {
7 mqd_t mqd;
8 void *buff;
9 ssize_t n;
10 sigset_t zeromask, newmask, oldmask;
11 struct mq_attr attr;
12 struct sigevent sigev;
13 if (argc != 2)
14 err_quit("usage: mqnotifysig2
15 /* открытие очереди, получение атрибутов, выделение буфера */
16 mqd = Mq_open(argv[1], O_RDONLY);
17 Mq_getattr(mqd, &attr);
18 buff = Malloc(attr.mq_msgsize);
19 Sigemptyset(&zeromask); /* сигналы не блокируются */
20 Sigemptyset(&newmask);
21 Sigemptyset(&oldmask);
22 Sigaddset(&newmask, SIGUSR1);
23 /* установка обработчика, включение уведомления */
24 Signal(SIGUSR1, sig_usr1);
25 sigev.sigev_notify = SIGEV_SIGNAL;
26 sigev.sigev_signo = SIGUSR1;
27 Mq_notify(mqd, &sigev);
28 for (;;) {
29 Sigprocmask(SIG_BLOCK, &newmask, &oldmask); /* блокируем SIGUSR1 */
30 while (mqflag == 0)
31 sigsuspend(&zeromask);
32 mqflag = 0; /* сброс флага */
33 Mq_notify(mqd, &sigev); /* перерегистрируемся */
34 n = Mq_receive(mqd, buff, attr.mq_msgsize, NULL);
35 printf("read %ld bytes\n", (long) n);
36 Sigprocmask(SIG_UNBLOCK, &newmask, NULL); /* разблокируем SIGUSR1 */
37 }
38 exit(0);
39 }
40 static void
41 sig_usr1(int signo)
42 {
43 mqflag = 1;
44 return;
45 }