某個空的消息隊列被放置一個消息時經過產生一個信號通知進程,進程取走消息。shell
#include <stdio.h> #include <stdlib.h> #include <mqueue.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #include <signal.h> volatile sig_atomic_t mqflag; // 被信息處理函數設置爲非0值 void sig_usr1(int); int main(int argc, char *argv[]) { mqd_t mqd; char *ptr; struct mq_attr attr; struct sigevent sigev; sigset_t zeromask, newmask, oldmask; // 信號集 unsigned int prio; size_t n; int rc; if(argc != 2) { printf("Usage: mqnotifysig3 <name>\n"); exit(1); } /*只讀模式打開消息隊列,同時指定非阻塞標誌*/ mqd = mq_open(argv[1], O_RDONLY); if(mqd < 0) { perror("打開消息隊列失敗"); exit(1); } /*取得消息隊列屬性*/ rc = mq_getattr(mqd, &attr); if(rc < 0) { perror("取得消息隊列屬性失敗"); exit(1); } /*動態申請保證能存放單條消息的內存*/ ptr = calloc(attr.mq_msgsize, sizeof(char)); if(NULL == ptr) { printf("動態申請內存失敗\n"); mq_close(mqd); exit(1); } /*初始化信號集*/ if(sigemptyset(&zeromask) < 0) {perror("初始化信號集失敗");} if(sigemptyset(&newmask) < 0) {perror("初始化信號集失敗");} if(sigemptyset(&oldmask) < 0) {perror("初始化信號集失敗");} if(sigaddset(&newmask, SIGUSR1) < 0) {perror("添加SIGUSR1信號失敗");} //註冊信號函數 signal(SIGUSR1, sig_usr1); sigev.sigev_notify = SIGEV_SIGNAL; sigev.sigev_signo = SIGUSR1; //註冊通知 rc = mq_notify(mqd, &sigev); // 讀取前須要再次註冊 if(rc < 0) { perror("通知註冊失敗"); mq_close(mqd); free(ptr); exit(1); } for(;;) { if(sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0 ) {perror("阻塞信號失敗");} while(0 == mqflag) { sigsuspend(&zeromask); /*等待信號到來*/ } mqflag = 0; rc = mq_notify(mqd, &sigev); // 讀取前須要再次註冊 if(rc < 0) { perror("通知註冊失敗"); mq_close(mqd); free(ptr); exit(1); } while((n = mq_receive(mqd, ptr, attr.mq_msgsize, &prio)) >= 0) { printf("Read %ld bytes\nPrio: %d\n", n, prio); } if(EAGAIN != errno) { perror("讀取失敗"); } sigprocmask(SIG_UNBLOCK, &newmask, NULL); } exit(0); } void sig_usr1(int signo) { mqflag = 1; return; }
編譯並執行:
[infor@s123 PosixMq]$ gcc -o mqnotifysig3 mqnotifysig3.c -lrt [infor@s123 PosixMq]$ ./mqnotifysig3 /tmp
程序阻塞在此處,等待其餘進程向消息隊列寫入消息。
另開一個會話,調用以前的寫消息程序:函數
[infor@s123 PosixMq]$ ./sendmq /tmp 100 10 [infor@s123 PosixMq]$ ./sendmq /tmp 90 9
能夠看到消息被讀了出來:
[infor@s123 PosixMq]$ gcc -o mqnotifysig3 mqnotifysig3.c -lrt [infor@s123 PosixMq]$ ./mqnotifysig3 /tmp Read 100 bytes Prio: 10 Read 90 bytes Prio: 9
2011-11-21 任洪彩 qdurenhongcai@163.comatom
轉載請註明出處。code