某个空的消息队列被放置一个消息时经过产生一个信号通知进程,进程取走消息。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