linux-IPC-消息队列

本文深入解析消息队列的概念,探讨其作为进程间通信机制的特点,包括数据结构、生命周期及消息发送接收过程。同时,介绍了创建、控制、发送和接收消息的函数,以及如何通过shell命令管理和删除队列。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

消息队列

消息队列是消息的链接表,存储在内核中,由消息队列标志符标识。

每个消息都包含一个正的长整型类型的字段、一个非负的长度以及实际的数据字节数,这些都在消息添加到队列时,传送给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》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值