消息队列
消息队列是消息的链接表,存储在内核中,由消息队列标志符标识。
每个消息都包含一个正的长整型类型的字段、一个非负的长度以及实际的数据字节数,这些都在消息添加到队列时,传送给msgsnd。msgrcv用于在队列中取消息,消息并不一定需要先进先出,可以根据消息类型字段来取。
特点
1.生命周期随内核,消息队列会一直存在,需要调用接口显式删除或使用命令删除
2.消息队列可以双向通信
3.克服了管道数据无格式字节流的缺点
数据结构
#include <msg.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;
};
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 */
};
消息队列函数
1.创建和引用一个消息队列
#include <sys/msg.h>
int msgget(key_t key, int flag);
key:某个消息队列的名字,用ftok()产生
flag:有两个选项,IPC_CREAT和IPC_EXCL,一般会使用IPC_CREAT|0664,设置文件权限
2.消息队列控制函数
#include <sys/msg.h>
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
msqid:消息队列标志码,由msgget返回
cmd:IPC_STAT 取此队列的msqid_ds结构,并将它存放在buf指向的结构中
IPC_SET 从buf指向的结构中(msg_perm.uid,msg_perm.gid,msg_perm.mode,msg_qbytes)复制到与这个队列相关的msqid_ds结构
IPC_RMID 从系统中删除该消息队列以及在消息队列中的所有数据,这种删除立即执行
IPC_SET 、IPC_RMID 只能由两种进程执行:有效ID等于msg_perm.uid、msg_perm.cuid,或者超级用户。
3.发送消息
#include <sys/msg.h>
int msgsnd(int msqid, const void *ptr, size_t nbytes, int flag);
ptr指向一个长整形数,包含了正的整形类型和实际要发的消息数据
flag参数可以指定为IPC_NOWAIT,设置为非阻塞型,msgsnd出错时立即返回EAGAIN,如果没指定该参数,则该进程会一直阻塞到:有空间容纳要发送的消息,或者从系统中删除该队列,或者捕捉到一个信号(EIDRM,标志被删除),从信号处理程序返回(EINTR)。
4.接收消息
#include <sys/msg.h>
ssize_t msgrcv(int msqid, void *ptr, size_t nbytes, long type, int flag);
成功则返回接收的实际字符个数,失败则返回-1
参数type ==0返回消息队列中的第一个消息
type >0返回消息类型为type的第一个消息
type <0返回队列中消息类型值小于等于type绝对值的消息,如果这种消息有若干个,则取类型值最小的消息。
shell cmdstring :
1.ipcs -q:显示IPC资源
2.ipcrm:手动删除IPC资源
与消息队列所提升的速度相比,它所带来的问题也不容忽视,因此不建议使用消息队列来IPC
参考书目:《APUE》