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

這是在Unix網絡編程第二捲進程間通信中看到的一個技巧。它使得posix消息隊列的mq_notify可以在select中使用。具體方法爲:
1、建立管道;
2、在主線程中用select監聽管道的讀事件;
3、在mq_notify的時間處理程序中往管道里寫數據,通知主線程
只是不知道這樣做,效率怎麼樣。

UNP-IPC有一段實例代碼,如下:
  1. 1 #include    "unpipc.h"  
  2.  2   
  3.  3 int        pipefd[2];  
  4.  4 static void    sig_usr1(int);  
  5.  5 /* $$.bp$$ */  
  6.  6 int  
  7.  7 main(int argc, char **argv)  
  8.  8 {  
  9.  9     int        nfds;  
  10. 10     char    c;  
  11. 11     fd_set    rset;  
  12. 12     mqd_t    mqd;  
  13. 13     void    *buff;  
  14. 14     ssize_t    n;  
  15. 15     struct mq_attr    attr;  
  16. 16     struct sigevent    sigev;  
  17. 17   
  18. 18     if (argc != 2)  
  19. 19         err_quit("usage: mqnotifysig5 <name>");  
  20. 20   
  21. 21         /* 4open queue, get attributes, allocate read buffer */  
  22. 22     mqd = Mq_open(argv[1], O_RDONLY | O_NONBLOCK);  
  23. 23     Mq_getattr(mqd, &attr);  
  24. 24     buff = Malloc(attr.mq_msgsize);  
  25. 25   
  26. 26     Pipe(pipefd);  
  27. 27   
  28. 28         /* 4establish signal handler, enable notification */  
  29. 29     Signal(SIGUSR1, sig_usr1);  
  30. 30     sigev.sigev_notify = SIGEV_SIGNAL;  
  31. 31     sigev.sigev_signo = SIGUSR1;  
  32. 32     Mq_notify(mqd, &sigev);  
  33. 33   
  34. 34     FD_ZERO(&rset);  
  35. 35     for ( ; ; ) {  
  36. 36         FD_SET(pipefd[0], &rset);  
  37. 37         nfds = Select(pipefd[0] + 1, &rset, NULL, NULL, NULL);  
  38. 38   
  39. 39         if (FD_ISSET(pipefd[0], &rset)) {  
  40. 40             Read(pipefd[0], &c, 1);  
  41. 41             Mq_notify(mqd, &sigev);            /* reregister first */  
  42. 42             while ( (n = mq_receive(mqd, buff, attr.mq_msgsize, NULL)) >= 0) {  
  43. 43                 printf("read %ld bytes\n", (long) n);  
  44. 44             }  
  45. 45             if (errno != EAGAIN)  
  46. 46                 err_sys("mq_receive error");  
  47. 47         }  
  48. 48     }  
  49. 49     exit(0);  
  50. 50 }  
  51. 51   
  52. 52 static void  
  53. 53 sig_usr1(int signo)  
  54. 54 {  
  55. 55     Write(pipefd[1], "", 1);    /* one byte of 0 */  
  56. 56     return;  
  57. 57 }  
  58. 58   
發佈了7 篇原創文章 · 獲贊 23 · 訪問量 25萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章