这是在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