消息队列是一个存放在内核中的消息链表,每个消息队列由消息队列标识符标识。与管道不同的是消息队列存放在内核中,
只有在内核重启(即操作系统重启)或者显式地删除一个消息队列时,该消息队列才会被真正删除。
几个重要的数据结构:
在文件/usr/include/linux/msg.h中
1、消息缓冲结构:
在向消息队列发送消息时,必须组合成合理的数据结构。linux定义了一个模板数据结构:
struct msgbuf {
long mtype; /* type of message 消息类型,必须 > 0 */
char mtext[1]; /* message text 消息正文,可以是其他任何类型*/
};
结构中的mytype字段代表消息类型。给消息指定类型,可以使得消息在一个队列中重复使用。mtext字段指消息内容。
注意:
mtext虽然定义为char类型,并不代表消息只能是一个字符,消息内容可以为任意类型,由用户根据需要定义。如下面
就是用户定义的一个消息结构:
struct MyMsgBuf {
long mtype; /* type of message */
struct student stu;
};
消息队列中的消息的大小是受限制的,由宏MSGMAX给出消息的最大长度。
2、msqid_ds内核数据结构
linux内核中,每个消息队列都维护一个结构体msqid_ds ,此结构体保存着消息队列当前的状态信息。
struct msqid_ds {
struct ipc_perm msg_perm;
struct msg *msg_first; /* first message on queue,unused */
struct msg *msg_last; /* last message in queue,unused */
__kernel_time_t msg_stime; /* last msgsnd time */
__kernel_time_t msg_rtime; /* last msgrcv time */
__kernel_time_t msg_ctime; /* last change time */
unsigned long msg_lcbytes; /* Reuse junk fields for 32 bit */
unsigned long msg_lqbytes; /* ditto */
unsigned short msg_cbytes; /* current number of bytes on queue */
unsigned short msg_qnum; /* number of messages in queue */
unsigned short msg_qbytes; /* max number of bytes on queue */
__kernel_ipc_pid_t msg_lspid; /* pid of last msgsnd */
__kernel_ipc_pid_t msg_lrpid; /* last receive pid */
};
各个字段的含义:
msg_perm:是一个ipc_perm(定义在头文件linux/ipc.h)的结构,保存了消息队列的存取权限,以及队列的用户ID、组ID等信息。
msg_first:指向队列中的第一条消息
msg_last:指向队列中的最后一条消息
msg_stime:向消息队列发送最后一条信息的时间
msg_rtime:从消息队列取最后一条消息的时间
msg_ctime:最后一次变更消息队列的时间
msg_lcbytes:消息队列中所有消息占的字节数
msg_qnum:消息队列中的消息数目
msg_qbytes:消息队列的最大字节数
msg_lspid:向消息队列发送最后一条消息的进程ID
msg_lrpid:从消息队列读取最后一条消息的进程ID
3、ipc_perm内核数据结构
结构体ipc_perm保存着消息队列的一些重要的信息,比如消息队列关联的键值,消息队列的用户ID,组ID等。
定义在linux/ipc.h中。
struct ipc_perm
{
__kernel_key_t key;
__kernel_uid_t uid;
__kernel_gid_t gid;
__kernel_uid_t cuid;
__kernel_gid_t cgid;
__kernel_mode_t mode;
unsigned short seq;
};
几个主要字段的含义如下:
key:创建消息队列用到的键值key
uid:消息队列的用户ID
gid:消息队列的组ID
cuid:创建消息队列的进程用户ID
cgid:创建消息队列进程组ID