Листинг 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
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 }
41 exit(0);
42 }
43 static void
44 sig_usr1(int signo)
45 {
46 Write(pipefd[1], "", 1); /* один байт – 0 */
47 return;
48 }