[Linux]System V 消息队列

介绍

消息队列是一种以链表式结构组织的数据,存放在内核中,是三个IPC对象类型中最具数据操作性的数据传送方式,可以根据数据类型来检索消息。
ipcs -q查看
ipcrm -q [msqid] 删除

消息队列创建/打开

int msgget(key_t key, int msgflg);
第一个参数key:给这个消息队列分配的密钥,同创建共享内存一样,系统返回对应共享内存的标识符,失败返回-1
第二个参数msgflg:IPC_CREAT如果不存在就创建,IPC_EXCL如果已经存在则返回失败,位或权限位:可以设置消息队列的访问权限

每创建一个消息队列,就会在用户空间组织这样的一个数据结构,用来设置或返回消息队列的信息。

struct msqid_ds {
    struct ipc_perm msg_perm;
    struct msg *msg_first; // 消息队列第一个节点
    struct msg *msg_last; // 消息队列最后一个节点
    unsigned short msg_cbytes; // 当前队列字节数据      
    unsigned short msg_qnum; // 队列中的消息数
    unsigned short msg_qbytes; // 队列中最大字节数
	...
	// 时间属性
    // 最近接收和发送消息的进程pid

};

其中ipc_perm结构体中组织了消息队列的key,创建/所有者ID和组ID,对象访问权限,消息队列中的消息数目。

当创建一个新的消息队列时,ipc_perm结构体中,创建/所有者ID被设置为当前用户ID,创建/所有者组ID被设置为当前用户组ID,其中对象访问权限被设置为msgflg,msg_ctime被设置为当前时间;msg_qbytes被设置为系统限制值MSGMNB。

添加消息到消息队列中

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
msgid:msgget函数返回的消息队列标识符
msgp:指向准备发送的消息,是一个用户自定义的结构体
msgsz:消息⻓度,不含消息类型,最大长度MSGMAX
msgflg:IPC_NOWAIT队列满非阻塞,返回EAGAIN错误,0阻塞

msgp的格式:
struct msgstru {
	long mtype;/*必须大于0*/
	char mtext[用户指定的大小]
}

将数据添加到队列尾,并且更新msg_last
在这里插入图片描述

从消息队列中接收消息

ssize_t msgrcv(int msqid,void *msgp,size_t msgsz,long msgtyp,int msgflg);
msgid:msgget函数返回的消息队列标识符
msgp:指针指向准备接收的消息
msgsz:是msgp指向的消息⻓度,不含消息类型
msgtype:它可以实现接收优先级的简单形式
若=0 - 读取消息队列中最早的消息,以先进先出的方式读取消息。
若> 0 - 读取消息队列类型为msgtyp最早的消息。
若< 0 - 读取消息队列中,消息类型小于或等于msgtyp绝对值的消息中最小消息类型的最早消息。
msgflg:IPC_NOWAIT设置非阻塞
成功返回实际放到msgp⾥去的字符个数,失败返回-1

控制消息队列

int msgctl(int msqid,int cmd,struct msqid_ds* buf);
msgid:msgget函数返回的消息队列标识符
通常cmd为IPC_RMID,buf为空,和共享内存相似

从内核看本质

内核维护着一个消息队列的全局数据结构ipc_ids,其中有一个指针指向一个数组。每当创建一个IPC对象内核就会创建一个ipc_perm,并且将它的地址放到结构体ipc_id中,这个数组就是这个结构体ipc_id组成的数组,数组最大的个数就是MSGMNI,所以说消息队列随内核持续,直到内核重新自举或者显示删除该对象为止。类似还有信号量、共享内存。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值