Linux IPC POSIX 消息队列
模型:
#include<mqueue.h>
#include <sys/stat.h>
#include <fcntl.h>
mq_open() //创建/获取消息队列fd
mq_get() //设置/获取消息队列属性
mq_send()/mq_receive() //发送/接收消息
mq_close() //脱接消息队列
mq_unlink() //删除消息队列
POSIX mq VS Sys V mq的优势
- 更简单的基于文件的应用接口
- 完全支持消息优先级(优先级最终决动队列中消息的位置)
- 完全支持消息到达的异步通知,这通过信号或是线程创建实现
- 用于阻塞发送与接收操作的超时机制
消息队列名
由$man mq_overview知:消息队列由一个形如'/somename'的名字唯一标识,名字字符串的最大长度不能朝着哦NAME_MAX(i.e.,255),两个进程通过使用同一个消息队列的名字来通信
mq_open()
//创建一个POSIX消息队列或打开一个已经存在的消息队列,成功返回消息队列描述符mqdes供其他函数使用,失败返回(mqd_t)-1设errno
//Link with -lrt.
mqd_t mq_open(const char *name, int oflag);
mqd_t mq_open(const char *name, int oflag, mode_t mode, struct mq_attr *attr);
oflag
must include one of:
- O_RDONLY表示以只接收消息的形式打开消息队列
- O_WRONLY表示以只发送消息的形式打开消息队列
- O_RDWR表示以可接收可发送的形式打开消息队列
can be Bitwised ORed:
- O_NONBLOCK以nonblocking的模式打开消息队列
- O_CREAT如果一个消息队列不存在就创建它,消息队列的拥有者的UID被设为调用进程的effective UID,GID被设为调用进程的effective GID
- O_EXCL确保消息队列被创建,如果消息队列已经存在,则发生错误
mode如果oflag里有O_CREAT,则mode用来表示新创建的消息队列的权限
attr如果oflag里有O_CREAT,则attr表示消息队列的属性,如果attr是NULL,则会按照默认设置配置消息队列(mq_overview(7) for details.)
mq_setattr() / mq_getattr()
//设置/修改 / 获取消息队列属性,成功返回0,失败返回-1设errno
//Link with -lrt.
int mq_setattr(mqd_t mqdes, const struct mq_attr *newattr, struct mq_attr *oldattr);
int mq_getattr(mqd_t mqdes, struct mq_attr *attr);
mqattr结构体
struct mq_attr {
long mq_flags; /* Flags: 0 or O_NONBLOCK */
long mq_maxmsg; /* Max. # of messages on queue */
long mq_msgsize; /* Max. message size (bytes) */
long mq_curmsgs; /* # of messages currently in queue */
};
mq_send() / mq_timesend()
//发送消息到mqdes指向的消息队列。成功返回0,失败返回-1设errno
//Link with -lrt.
int mq_send(mqd_t mqdes, const char *msg_ptr,size_t msg_len, unsigned int msg_prio);
//如果消息队列满
#include<time.h> //额外的header
int mq_timedsend(mqd_t mqdes, const char *msg_ptr,size_t msg_len, unsigned int msg_prio,const struct timespec *abs_timeout);
msg_len msg_ptr指向的消息队列的长度,这个长度必须<=消息队列中消息长度,可以是0
**msg_prio **一个用于表示消息优先级的非0整数,消息按照优先级递减的顺序被放置在消息队列中,同样优先级的消息,新的消息在老的之后,如果消息队列满了,就进入blocked状态,新的消息必须等到消息队列有空间了进入,或者调用被signal中断了。如果flag里有O_NOBLOCK选项,则此时会直接报错
abs_timeout:如果消息队列满了,那么就根据abs_timeout指向的结构体表明的时间进行锁定,里面的时间是从970-01-01 00:00:00 +0000 (UTC)开始按微秒计量的时间,如果时间到了,那么mq_timesend()立即返回
struct timespec {
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
mq_receive()/mq_timedreceive()
//从消息队列中取出优先级最高的里面的最老的消息,成功返回消息取出消息的大小,失败返回-1设errno
//具体功能参照mq_send()/mq_timesend()
//Link with -lrt.
ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned int *msg_prio);
#include<time.h> //额外的header
ssize_t mq_timedreceive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned int *msg_prio, const struct timespec *abs_timeout);
mq_notify()
//允许调用进程注册或去注册同步来消息的通知,成功返回0,失败返回-1设errno
//Link with -lrt.
int mq_notify(mqd_t mqdes, const struct sigevent *sevp);
sevp指向sigevent的指针
- 如果sevp不是NULL,那么这个函数就将调用进程注册到通知进程,只有一个进程可以被注册为通知进程
- 如果sevp是NULL且当前进程已经被注册过了,则去注册,以便其他进程注册
union sigval { /* Data passed with notification */
int sival_int; /* Integer value */
void* sival_ptr; /* Pointer value */
};
struct sigevent {
int sigev_notify; /* Notification method */
int sigev_signo; /* Notification signal */
union sigval sigev_value; /* Data passed with notification */
void(*sigev_notify_function) (union sigval); //Function used for thread notification (SIGEV_THREAD)
void* sigev_notify_attributes; // Attributes for notification thread (SIGEV_THREAD)
pid_t sigev_notify_thread_id; /* ID of thread to signal (SIGEV_THREAD_ID) */
};
sigev_notify使用下列的宏进行配置:
- SIGEV_NONE调用进程仍旧被注册,但是有消息来的时候什么都不通知
- SIGEV_SIGNAL通过给调用进程发送sigev_signo指定的信号来通知进程有消息来了
- SIGEV_THREAD一旦有消息到了,就激活sigev_notify_function作为新的线程的启动函数
mq_close()
//关闭消息队列描述符mqdes,如果有进程存在针对这个队列的notification request,那么也会被移除
//成功返回0,失败返回-1设errno
//Link with -lrt.
int mq_close(mqd_t mqdes);
mq_unlink():
//移除队列名指定的消息队列,一旦最后一个进程关闭了针对这个消息队列的描述符,就会销毁这个消息队列
//成功返回0,失败返回-1设errno
//Link with -lrt.
int mq_unlink(const char *name);
Linux IPC POSIX 消息队列的更多相关文章
- UNIX IPC: POSIX 消息队列 与 信号
POSIX消息队列可以注册空队列有消息到达时所触发的信号,而信号触发对应的信号处理函数. 下面是一份基本的消息队列和信号处理结合的代码(修改自UNIX网络编程:进程间通信) #include < ...
- UNIX IPC: POSIX 消息队列
首先在我的MAC OSX上试了一下虽然有_POSIX_MESSAGE_PASSING的宏定义,但是用gcc编译会提示没有mqueue.h头文件,先放一边.在Ubuntu上使用正常,不过POSIX消息队 ...
- Linux IPC实践(7) --Posix消息队列
1. 创建/获取一个消息队列 #include <fcntl.h> /* For O_* constants */ #include <sys/stat.h> /* For m ...
- Linux进程间通信(IPC)编程实践(十二)Posix消息队列--基本API的使用
posix消息队列与system v消息队列的区别: (1)对posix消息队列的读总是返回最高优先级的最早消息,对system v消息队列的读则能够返回随意指定优先级的消息. (2)当往一个空队列放 ...
- Linux环境编程之IPC进程间通信(五):Posix消息队列1
对于管道和FIFO来说.必须应该先有读取者存在.否则先有写入者是没有意义的. 而消息队列则不同,它是一个消息链表,有足够写权限的线程可往别的队列中放置消息,有足够读权限的线程可从队列中取走消息.每一个 ...
- Unix IPC之Posix消息队列(1)
部分参考:http://www.cnblogs.com/Anker/archive/2013/01/04/2843832.html IPC对象的持续性:http://book.51cto.com/ar ...
- IPC通信:Posix消息队列
IPC通信:Posix消息队列 消息队列可以认为是一个链表.进程(线程)可以往里写消息,也可以从里面取出消息.一个进程可以往某个消息队列里写消息,然后终止,另一个进程随时可以从消息队列里取走这些消息. ...
- [转]Linux进程通信之POSIX消息队列
进程间的消息队列可以用这个实现,学习了下. http://blog.csdn.net/anonymalias/article/details/9799645?utm_source=tuicool&am ...
- Linux 进程间通信(posix消息队列 简单)实例
Linux 进程间通信(posix消息队列 简单)实例 详情见: http://www.linuxidc.com/Linux/2011-10/44828.htm 编译: gcc -o consumer ...
随机推荐
- Java在方法作用域内创建的内部类
在方法作用域内创建的内部类,用来实现一个接口 /** * Created by xfyou on 2016/11/3. * Java内部类演示 */ public class Parcel3 { pu ...
- 初识Hibernate 缓存
生活就像一杯咖啡,让你我慢慢的品尝,品尝它的苦涩和甘甜...... 一.什么是Hibernate缓存. 解析:白话来说就是缓存数据的容器 官方标准点缓存:是计算机领域的概念,它介于应用程序和永久性数据 ...
- ArcGIS server 开发实践之【FeatureLayer类】
全是干活,你值得拥有 要素图层类简介:Class:FeatureLayer //调用方式:require(["esri/layers/FeatureLayer"],function ...
- ZeroClipboard 复制到剪贴板
使用 ZeroClipboard 可以简单的将内容复制到剪贴板,通过 Adobe Flash 和 JavaScript 来实现.“Zero” 意义为这个类库没有界面,界面需要由你来建立. 版本: Ze ...
- Sticker.js – 帮助你在网站中加入贴纸效果
Sticker.js 是一个很小的 JavaScript 库,它允许您在网页中创建漂亮的贴纸效果.没有依赖关系(不需要 jQuery),可以在大多数支持 CSS3 的主流浏览器工作.下面有简单的使用示 ...
- MAC下利用Github 、hexo、 多说、百度统计 建立个人博客指南
1.前期准备: (1)注册github账号 (2)安装xcode (3)安装node.js 2.创建repository: (1)开个github的个人主页,点击创建仓库按钮 New reposito ...
- SQL Server SQL分页查询
SQL Server SQL分页查询的几种方式 目录 0. 序言 1. TOP…NOT IN… 2. ROW_NUMBER() 3. OFFSET…FETCH 4. 执行 ...
- 关于WPF中文件夹浏览对话框的方式
文件夹浏览时dialogresult要写全引用路径 string path=null; FolderBrowserDialog fbd = new FolderBrowserDialog(); fbd ...
- [SQL] SQL Server 触发器
触发器是一种特殊类型的存储过程,它不同于之前的我们介绍的存储过程.触发器主要是通过事件进行触发被自动调用执行的.而存储过程可以通过存储过程的名称被调用. Ø 什么是触发器 触发器对表进行插入.更新.删 ...
- Sharepoint学习笔记—习题系列--70-576习题解析 -(Q75-Q77)
Question 75You are designing a feature for a SharePoint 2010 solution that will be activated by defa ...