Linux POSIX IPC 消息队列
模型:创建/获取消息队列fd :mq_open()
设置/获取消息队列属性 :mq_get()
发送/接收消息 :mq_send()/mq_receive()
脱接消息队列 :mq_close()
删除消息队列 :mq_unlink()
头文件 #include<mqueue.h> #include <sys/stat.h> #include <fcntl.h> 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.)
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()立即返回
sevp指向sigevent的指针
如果sevp不是NULL,那么这个函数就将调用进程注册到通知进程,只有一个进程可以被注册为通知进程