(三) 消息队列
1.每个队列都有一个msqid_ds结构与之相关联:
struct msqid_ds{
struct ipc_perm msg_perm;
msgqnum_t msg_qnum; //消息的数量
msglen_t msg_qbytes; //最大消息的长度
pid_t msg_lspid; //最后一个发送到消息队列的进程ID
pid_t msg_lrpid; //最后一个读取消息的进程ID
time_t msg_stime; //最后一次发送到消息队列的时间
time_t msg_rtime; //最后一次读取消息的时间
time_t msg_ctime; //最后一次改变的时间
。
。
。
};
struct ipc_perm{
uid_t uid;//拥有者有效的用户ID
gid_t gid;//拥有者有效的组ID
uid_t cuid;//创建者有效的用户ID
uid_t cgid;//创建者有效的组ID
mode_t mode; //权限
。
。
}
2.#include <sys/msg.h> int msgget(key_t key, int flag);
//打开一个现存的队列或创建一个新队列;成功返回0,出错返回-1
3.int msgctl(int msqid, int cmd, struct msqid_ds *buf);//对消息队列执行多种操作
cmd 可选:
IPC_STAT 取此消息队列的msqid_ds结构,并将它放在buf指向的结构
IPC_SET:按由buf指向结构中的值,设置与此队列相关结构中的下列四个字段:msg_perm.uid,msg_perm.gid,msg_perm.mode和msg_qbytes.此命令只有下列两种进程才能执行(1)其有效用户ID等于msg_perm.cuid或msg_perm.uid;(2)具有超级用户特权的进程
IPC_RMID:从系统中删除消息队列以及仍在该队列中的所有数据。
成功返回0,失败返回-1
4.int msgsnd(int msqid, const void *ptr, size_t nbytes, int flag)//发送消息到消息队列中
成功返回0, 不成功返回-1并设置errno,错误码:
EACCES 对调用程序来说,调用被否定
EAGAIN 操作会阻塞进程,但(msgflg & IPC_NOWAIT) != 0
EIDRM msqid已经从系统中删除了
EINTR 函数被信号中断
EINVAL 参数msqid无效,消息类型<1,或者msgsz越界了
flag可以指定为IPC_NOWAIT 则不会阻塞直接返回EAGAIN
注:参数msgp指向用户定义的缓冲区,他是如下的结构
struct mymsg
{
long mtypes; 消息类型
char *mtext; 消息文本
}mymsg_t
5.ssize_t msgrcv(int msqid, void *ptr, size_t nbytes, long type, int flag);//读取消息
成功则返回消息的数据部分的长度,出错则返回-1
type: type==0返回队列中的第一个消息
type>0 返回队列中消息类型为type的第一个消息
type<0返回队列中消息类型值小于或等于type绝对值的消息(多个取类型值最小的)