在LINUX进程间通信方法有很多种,其中有消息队列、信号量、共享内存,而这三种进程间通信方法又分为System V IPC 和 POSIX IPC 两类。
接下来要探讨的是POSIX的消息对列(实际编程中用得相对多一些)。
先将POSIX 消息对列函数列表放出来:
#include <mqueue.h>
//打开/创建一个消息队列
mqd_t mq_open(const char *name, int oflag, ...)
mqd_t mq_open(const char *name, int oflag, mode_t mode, mq_attr* attr)
//关闭消息队列
int mq_close(mqd_t mqdes);
//销毁消息队列
int mq_unlink(const char *name);
//发送消息
int mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio);
//接收消息
ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio);
//通知进程获取消息
int mq_notify(mqd_t mqdes, const struct sigevent *sevp);
//获取消息属性
int mq_getattr(mqd_t mqdes, struct mq_attr *attr);
//设置消息属性
int mq_setattr(mqd_t mqdes, struct mq_attr *newattr, struct mq_attr *oldattr);
mq_open用于打开或创建一个消息队列,通过一个消息队列描述符(类型是mqd_t)建立一个进程与一个消息队列的连接.
代码片段:
mqd = mq_open("mq_0", flags, S_IRUSR | S_IWUSR, NULL);
if(mqd == -1)
{
fprintf(stderr, "mq_open failed (%s)\n", strerror(errno));
return -2;
}
while(1)
sleep(11);
mq_close(mqd);
在/proc/PID/fd目录下,也可以看到消息队列对应的文件描述符:
可以看到,消息队列mq_0已经创建出来了。
那么,一个进程允许我们创建多少个消息队列呢?每个消息队列携带的消息的最大字节数是多少呢?
其实标准并没有严格限定,这点是由具体的实现来决定的。SUSv3 标准要求这个限制最小为_POSIX_MQ_OPEN_MAX(8)。
Linux没有定义这个限制。在LINUX中,因为消息描述符被实现成了文件描述符,因此其必须遵循文件描述符的限制。
进程允许打开的消息队列个数是否仅仅受限于进程打开的最大文件个数?事实上并非如此。资源限制中有一项RLIMIT_MSGQUEUE,用于限制用户在POSIX消息队列中可以分配的最大字节数。这个后面再讲。
mq_open函数第四个参数是mq_attr类型的,表示消息队列的属性。创建时可以指定消息队列的属性,设置为NULL则采用系统默认属性值,POSIX消息队列也提供 了mq_setattr函数来改变消息队列的属性。
属性类型定义:
/include/uapi/linux/mqueue.h
struct mq_attr {
__kernel_long_t mq_flags; /* message queue flags */
__kernel_long_t mq_maxmsg; /* maximum number of messages */
__kernel_long_t mq_msgsize; /* maximum message size */
__kernel_long_t mq_curmsgs; /* number of messages currently queued */
__kernel_long_t __reserved[4]; /* ignored for input, zeroed for output */
};
.mq_flags:0或设置了O_NONBLOCK。
·mq_maxmsg:消息队列中的最大消息个数。
·mq_msgsize:单条消息允许的最大字节数。
·mq_curmsgs:消息队列当前的消息个数。
可以使用如下代码来获取默认属性:
int ret = mq_getattr(mqd, &attr);
if(ret != 0)
{
fprintf(stderr, "failed to get attr(%d: %s)\n", errno, strerror(errno));
return 2;
}
fprintf(stdout, "the default mq_maxmsg = %ld\nthe default mq_msgsize = %ld\n", attr.mq_maxmsg, attr.mq_msgsize);
其输出如下:
the default mq_maxmsg = 10
the default mq_msgsize = 8192
从输出可以看出,默认情况下,消息队列的最大消息数为10,单条消息的最大字节数为8192字节。
我们也可以从系统文件中查看,其中消息队列的相关信息记录在如下位置:
其中消息队列的最大消息数的默认值记录在msg_default:
cat /proc/sys/fs/mqueue/msg_default