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

用管道(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 



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