博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【IPC通信】Posix消息队列使用异步事件通知
阅读量:5810 次
发布时间:2019-06-18

本文共 2693 字,大约阅读时间需要 8 分钟。

  hot3.png

mq_notify()函数为指定队列建立或删除异步事件通知,建立通知即某空消息队列中如有新的消息,会发送一个信号或创建一个线程来执行指定的函数。

#include 
int mq_notify(mqd_t mqdes, const struct sigevent *notification);成功返回0,出错则为-1

给出struct sigevent定义:

union signal{    int  sival_int;  /*整数值*/    void *sival_ptr; /*指针值*/};struct sigevent{    int sigev_notify; /*通知类型:SIGEV_NONE、SIGEV_SIGNAL、SIGEV_THREAD*/    int sigev_signo; /*信号值*/    union sigval sigev_value; /*传递给信号处理函数或线程的信号值*/    void (*sigev_notify_function)(union sigval); /*线程处理函数*/    pthread_attr_t *sigev_notify_attributes; /*线程属性*/};

下面给出示例代码:

#include 
#include
#include
#include
#include
#include
#include
#include
#include
mqd_t mqd;struct mq_attr attr;struct sigevent sigev;char *ptr;unsigned int prio;size_t n;int rc;void sig_usr1(int signo);/*读取某消息队列,消息队列名通过参数传递*//*当有消息放置到某个空的队列中时产生SIGUSR1信号*/int main(int argc, char *argv[]){ if(argc != 2) { printf("Usage: mqnotifysig1
\n"); exit(1); } /*只读模式打开消息队列*/ mqd = mq_open(argv[1], O_RDONLY); if(mqd < 0) { perror("打开消息队列失败"); exit(1); } // 取得消息队列属性,根据mq_msgsize动态申请内存 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); } //注册信号函数 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(;;) { pause(); } return 0;}void sig_usr1(int signo){ rc = mq_notify(mqd, &sigev); // 读取前需要再次注册 if(rc < 0) { perror("通知注册失败"); mq_close(mqd); free(ptr); exit(1); } /*接收一条消息*/ n = mq_receive(mqd, ptr, attr.mq_msgsize, &prio); if(n < 0) { perror("读取失败"); mq_close(mqd); free(ptr); exit(1); } printf("读取 %ld 字节\n优先级为 %u\n", (long)n, prio);}

编译并执行:

[infor@s123 PosixMq]$ gcc -o mqnotifysig1 mqnotifysig1.c -lrt[infor@s123 PosixMq]$ ./mqnotifysig1 /tmp

此时消息队列内没有消息,程序进入睡眠,等待信号到来。再开启一个终端,通过另外的程序往消息队列写消息:

[infor@s123 PosixMq]$ ./sendmq /tmp 200 16[infor@s123 PosixMq]$ ./sendmq /tmp 100 17[infor@s123 PosixMq]$ ./sendmq /tmp 50 18

可以看到先前的程序:

[infor@s123 PosixMq]$ gcc -o mqnotifysig1 mqnotifysig1.c -lrt[infor@s123 PosixMq]$ ./mqnotifysig1 /tmp读取 200 字节优先级为 16读取 100 字节优先级为 17读取 50 字节优先级为 18

mq_notify函数使用规则:

1、如果mq_notify()的notification参数非空,则表明将当前进程注册为接收某队列的通知;

2、如果mq_notify()的notification参数为空,则表明之前已存在的注册将被撤消;
3、一个消息队列任意时刻只能由一个进程注册;
4、如有其他进程mq_receive阻塞在该消息队列时,信号不会发出,即mq_receive调用优先级更高;
5、通知被发送给注册进程时,注册即被撤消,须重新注册。

注:上面程序其实是有问题,本处只做mq_notify函数的使用示例。

 

2011-11-18  任洪彩  qdurenhongcai@163.com

转载请注明出处。

转载于:https://my.oschina.net/renhc/blog/35539

你可能感兴趣的文章
系统版本判断
查看>>
My97DatePicker 日历插件
查看>>
0603 学术诚信与职业道德
查看>>
小点心家族第3位成员——楼层定位效果
查看>>
Knockout.Js官网学习(enable绑定、disable绑定)
查看>>
hive基本操作与应用
查看>>
excel快捷键设置
查看>>
poj3692
查看>>
python之信号量【Semaphore】
查看>>
html5纲要,细谈HTML 5新增的元素
查看>>
Android应用集成支付宝接口的简化
查看>>
[分享]Ubuntu12.04安装基础教程(图文)
查看>>
[Vim] 搜索模式(正则表达式)
查看>>
#HTTP协议学习# (二)基本认证
查看>>
Android开发之线性布局详解(布局权重)
查看>>
WCF
查看>>
django 目录结构修改
查看>>
win8 关闭防火墙
查看>>
Android实例-录音与回放(播放MP3)(XE8+小米2)
查看>>
CSS——(2)与标准流盒模型
查看>>