用管道(pipe)使消息队列通知(mq_notify)可以在Select和poll中使用

这是在Unix网络编程第二卷进程间通信中看到的一个技巧。它使得posix消息队列的mq_notify可以在select中使用。具体方法为:
1、建立管道;
2、在主线程中用select监听管道的读事件;
3、在mq_notify的时间处理程序中往管道里写数据,通知主线程
只是不知道这样做,效率怎么样。

UNP-IPC有一段实例代码,如下:
1 #include    "unpipc.h"
 2 
 3 int        pipefd[2];
 4 static void    sig_usr1(int);
 5 /* $$.bp$$ */
 6 int
 7 main(int argc, char **argv)
 8 {
 9     int        nfds;
10     char    c;
11     fd_set    rset;
12     mqd_t    mqd;
13     void    *buff;
14     ssize_t    n;
15     struct mq_attr    attr;
16     struct sigevent    sigev;
17 
18     if (argc != 2)
19         err_quit("usage: mqnotifysig5 <name>");
20 
21         /* 4open queue, get attributes, allocate read buffer */
22     mqd = Mq_open(argv[1], O_RDONLY | O_NONBLOCK);
23     Mq_getattr(mqd, &attr);
24     buff = Malloc(attr.mq_msgsize);
25 
26     Pipe(pipefd);
27 
28         /* 4establish signal handler, enable notification */
29     Signal(SIGUSR1, sig_usr1);
30     sigev.sigev_notify = SIGEV_SIGNAL;
31     sigev.sigev_signo = SIGUSR1;
32     Mq_notify(mqd, &sigev);
33 
34     FD_ZERO(&rset);
35     for ( ; ; ) {
36         FD_SET(pipefd[0], &rset);
37         nfds = Select(pipefd[0] + 1, &rset, NULL, NULL, NULL);
38 
39         if (FD_ISSET(pipefd[0], &rset)) {
40             Read(pipefd[0], &c, 1);
41             Mq_notify(mqd, &sigev);            /* reregister first */
42             while ( (n = mq_receive(mqd, buff, attr.mq_msgsize, NULL)) >= 0) {
43                 printf("read %ld bytes\n", (long) n);
44             }
45             if (errno != EAGAIN)
46                 err_sys("mq_receive error");
47         }
48     }
49     exit(0);
50 }
51 
52 static void
53 sig_usr1(int signo)
54 {
55     Write(pipefd[1], "", 1);    /* one byte of 0 */
56     return;
57 }
58 
转自http://www.cppblog.com/mildforest/archive/2011/02/24/140611.aspx

你可能感兴趣的:(用管道(pipe)使消息队列通知(mq_notify)可以在Select和poll中使用)