概述
对于系统中的每个消息队列,内核维护一个定义在 <sys/msg.h> 头文件中的信息结构:
msqid_ds
c
struct msqid_ds { // structure describing operation permission struct ipc_perm msg_perm; // current number of bytes on queue unsigned long __msg_cbytes; // number of messages currently on queue msgqnum_t msg_qnum; // max number of bytes allowed on queue msglen_t msg_qbytes; // pid of last msgsnd() pid_t msg_lspid; // pid of last msgrcv() pid_t msg_lrpid; // time of last msgsnd() time_t msg_stime; // time of last msgrcv() time_t msg_rtime; // time of last msgctl() time_t msg_ctime; }
msgget
msgget 用于创建一个新的消息队列或访问一个已存在的消息队列。
code
c
#include <sys/msg.h> int msgget(key_t key, int oflag);
msgget 返回一个整数标识符,其它三个 msg 函数将用该标识符来指代该队列。标识符是基于参数 key
产生的,而 key
既可以是 ftok 的返回值,也可以是常值 IPC_PRIVATE
。
oflag
为 IPC 机制的权限位:
数字值(八进制) | 符号值 | 说明 | ||
---|---|---|---|---|
消息队列 | 信号量 | 共享内存区 | ||
0400 0200 |
MSG_R MSG_W |
SHM_R SHM_A |
SHM_R SHM_W |
由用户(属主)读 由用户(属主)写 |
0040 0020 |
MSG_R >> 3 MSG_W >> 3 |
SHM_R >> 3 SHM_A >> 3 |
SHM_R >> 3 SHM_W >> 3 |
由(属)组成员读 由(属)组成员写 |
0004 0002 |
MSG_R >> 6 MSG_W >> 6 |
SHM_R >> 6 SHM_A >> 6 |
SHM_R >> 6 SHM_W >> 6 |
由其他用户读 由其他用户写 |
在此处还可以与 IPC_CREAT
、IPC_IPC_CREAT | IPC_EXCL
按位或,这将会在后续内容讨论。
当创建一个新消息队列时,msqid_ds 结构的如下成员被初始化:
-
msg_perm 结构的 uid 和 cuid 成员被置成当前进程的有效用 ID,gid 和 cgid 被置成当前进程的有效组 ID。
-
oflag
中的读写权限位存放在 msg_perm.mode 中。 -
msg_qnum、msg_lspid、msg_lrpid、msg_stime 和 msg_rtime 被置为 0。
-
msg_ctime 被置成当前时间。
-
msg_qbytes 被置成系统限制值。
msgsnd
使用 msgget 打开一个消息队列后,可以使用 msgsnd 往其上放置一个消息。
code
c
#include <sys/msg.h> // 成功返回 0,出错返回 -1 int msgsnd(int msqid, const void *ptr, size_t length, int flag);
其中 msqid
是 msgget 返回的标识符,ptr
是一个结构体指针,该结构具有以下的模板,定义在 <sys/msg.h> 中:
msgbuf
c
struct msgbuf { // message type, must be > 0 long mtype; // message data char mtext[1]; }
消息类型必须大于 0,因为对于 msgrcv 函数来说,非正的消息类型用做特殊的指示器,这将在后续内容讲述。