Posix消息队列(message queue)
IPC函数中常用的参数取值:
打开或创建POSIX IPC对象所用的各种oflag常值o_RDONLY 只读
O_WRONLY 只写
O_RDWD 读写
O_CREAT 若不存在则创建,存在则引用
O_EXCL 排他性创建,需要和O_CREAT一起使用,当对象不存在时才创建,否则返回EEXIST错误
O_NONBLOCK 非阻塞模式
O_TRUNC 若已存在则截短
创建新的IPC对象所用的mode常值:
S_IRUSR 用户(属主)读S_IWUSR 用户(属主)写
S_IRGRP 属组读
S_IWGRP 属组写
S_IROTH 其他用户读
S_IWOTH 其他用户写
mq_open()函数:
#include <mqueue.h> // 创建一个新的消息队列,或打开一个已存在的消息队列 // 成功返回消息队列描述符,出错 返回-1 mqd_t mq_open(const char *name, int oflag, ... /* mode_t mode, struct mq_attr *attr */); // name:Posix IPC名字(标识符) // oflag取值: o_RDONLY、O_WRONLY、O_RDWD,可能按位或上O_CREAT、O_EXCL、O_NONBLOCK // attr: 消息队列的属性(可以不指定此参数)
mq_close()函数:
#include <mqueue.h> // 关闭一个打开着的消息队列,但不从系统中将其删除,成功返回0,出错返回-1 int mq_close(mqd_t mqdes);
mq_unlink()函数:
#include <mqueue.h> // 从系统中删除一个消息队列,成功返回0,出错返回-1 int mq_unlink(const char *pathname);
注意:
大家可能在close和unlink之间存在疑惑,而除了此处的close和unlink,还有对文件的close和unlink
面对不同对象的close和unlink,表示的含义其实是相同的,close(关闭)即关闭open打开的对某个对
象的访问通道,而对于对象本身存在与否(创建/删除)没有影响,而unlink影响的是某个对象是否存在
一旦对某个对象的链接数(link)为0,且该对象没有被open,则该对象就会被彻底删除
上述的对象(File、Message Queue...等)
消息队列的属性:
struct mq_attr{ long mq_flags; // 消息队列的标志 long mq_maxmsg; // 队列允许的最大消息数量 long mq_msgsize; // 消息的最大长度(bytes) long mq_curmsgs; // 此时存在与队列中的消息数量 };
mq_getattr()和mq_setattr()函数:
#include <mqueue.h> // 成功返回0,出错返回-1 // 将当前消息队列的属性填入参数attr指向的结构中 int mq_getattr(mqd_t mqdes, struct mq_attr *attr); // 给指定队列设置属性(attr,但只使用attr的attr.mq_flags成员),当oattr非空时,将指定队列的先前属性填入其中 int mq_setattr(mqd_t mqdes, const struct mq_attr *attr, struct mq_attr *oattr);
mq_send()和mq_receive()函数:
#include <mqueue.h> // 成功返回0,出错返回-1 // 往消息队列中放置一个消息 int mq_send(mqd_t mqdes, const char *ptr, size_t len, unsigned int prio); // prio: 待发消息的优先级 // 成功返回消息的字节数,出错返回-1 // 从消息队列取出一个消息 ssize_t mq_receive(mqd_t mqdes, const char *ptr, size_t len, unsigned int *priop); // 这里的len参数值不能小于能添加到指定队列中消息的最大大小(mq_attr.mq_msgsize)
mq_notify()函数:
#include <mqueue.h> // 成功返回0,出错返回-1 // 指定队列建立或删除异步事件通知 int mq_notify(mqd_t mqdes, const struct sigevent *notification);
相关结构:
union sigval{ int sival_int; void *sival_ptr; }; struct sigevent{ int sigev_notify; int sigev_signo; union sigval sigev_value; void (*sigev_notify_function)(union sigval); pthread_attr_t *sigev_notify_attributes; };