顾名思义, 消息队列就是一些消息的列表, 用户可以在消息队列中添加消息和读取消息等。从这点上看, 消息队列具有一定的 FIFO 特性, 但是它可以实现消息的随机查询, 比 FIFO具有更大的优势。 同时, 这些消息又是存在于内核中的, 由“队列 ID” 来标识。
消息队列的实现包括创建或打开消息队列、 添加消息、 读取消息和控制消息队列 4 种操作,
创建或打开消息队列使用的函数是 msgget(), 这里创建的消息队列的数量会受到系统消息队列数量的限制;
添加消息使用的函数是 msgsnd(), 它把消息添加到已打开的消息队列末尾;
读取消息使用的函数是 msgrcv(), 它把消息从消息队列中取走, 与 FIFO 不同的是,这里可以取走指定的某一条消息;
控制消息队列使用的函数是 msgctl(), 它可以完成多项功能。
msgget()函数的语法要点。
函数原型int msgget(key_t key, int msgflg)
函数传入值
key: 消息队列的键值, 多个进程可以通过它访问同一个消息队列, 其中有个特殊值IPC_PRIVATE, 用于创建当前进程的私有消息队列
msgflg: 权限标志位
函数返回值
成功: 消息队列 ID
出错: 1
msgsnd()函数的语法要点。
函数原型
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg)
函数传入值
msqid: 消息队列的队列 ID
msgp: 指向消息结构的指针, 该消息结构 msgbuf 通常如下。扫描二维码关注公众号,回复: 3429024 查看本文章
- struct msgbuf
- {
- long mtype; /* 消息类型, 该结构必须从这个域开始 */
- char mtext[1]; /* 消息正文 */
- }
msgsz: 消息正文的字节数(不包括消息类型指针变量)
msgflg:
- IPC_NOWAIT: 若消息无法立即发送(如当前消息队列已满) , 函数会立即返回
- 0: msgsnd 调用阻塞直到发送成功为止
函数返回值
成功: 0
出错: 1
msgrcv()函数的语法要点。
函数原型
int msgrcv(int msgid, void *msgp, size_t msgsz, long int msgtyp, int msgflg)
函数传入值msqid: 消息队列的队列 ID
msgp: 消息缓冲区, 同 msgsnd()函数的 msgp
msgsz: 消息正文的字节数(不包括消息类型指针变量)
msgtyp:
- 0: 接收消息队列中第一个消息
- 大于 0: 接收消息队列中第一个类型为 msgtyp 的消息续表
- 小于 0: 接收消息队列中第一个类型值不小于 msgtyp 绝对值且类型值最小的消息
msgflg:
- MSG_NOERROR:若返回的消息比 msgsz 字节多,则消息就会截短到 msgsz字节, 且不通知消息发送进程
- IPC_NOWAIT: 若在消息队列中并没有相应类型的消息可以接收, 则函数立即返回
- 0: msgsnd()调用阻塞直到接收一条相应类型的消息为止
函数返回值
成功: 0
出错: 1
重要结构体:
struct msqid_ds {
struct ipc_perm msg_perm; /* Ownership and permissions */
time_t msg_stime; /* Time of last msgsnd(2) */
time_t msg_rtime; /* Time of last msgrcv(2) */
time_t msg_ctime; /* Time of last change */
unsigned long __msg_cbytes; /* Current number of bytes in
queue (nonstandard) */
msgqnum_t msg_qnum; /* Current number of messages
in queue */
msglen_t msg_qbytes; /* Maximum number of bytes
allowed in queue */
pid_t msg_lspid; /* PID of last msgsnd(2) */
pid_t msg_lrpid; /* PID of last msgrcv(2) */
};
//The ipc_perm structure is defined as follows (the highlighted fields are settable using IPC_SET):
struct ipc_perm {
key_t __key; /* Key supplied to msgget(2) */
uid_t uid; /* Effective UID of owner */
gid_t gid; /* Effective GID of owner */
uid_t cuid; /* Effective UID of creator */
gid_t cgid; /* Effective GID of creator */
unsigned short mode; /* Permissions */
unsigned short __seq; /* Sequence number */
};