Linux消息队列

本文详细介绍了Linux中的消息队列,它是一种链表形式的内核数据结构,用于进程间通信。文章涵盖了消息队列的定义、创建、发送和接收消息的方法,以及如何销毁和查看消息队列。重点讨论了消息队列的特性,如面向数据块、数据类型标识和优先级接受。

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

Linux中的消息队列是进程间通信的一种方式,通过创建一个消息队列可以完成一个或者多个进程的信息交汇。因此,首先我们要了解消息队列是什么。

消息队列的定义

消息队列的本质其实是一个内核提供的链表,内核基于这个链表,实现了一个数据结构,并且通过维护这个数据结构来维护这个消息队列。向消息队列中写数据,实际上是向这个数据结构中插入一个新结点;从消息队列汇总读数据,实际上是从这个数据结构中删除一个结点。

消息队列的创建

消息队列的创建通过调用msgget()函数来创建,函数原型为:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgget(key_t key, int msgflg);

参数key相当于文件系统的文件名,msgflg是一个操作指令,当想要创建一个消息队列时可以填IPC_CREAT | 0644,前面指的是创建的指令,后面的0644指的是消息队列的执行权限,因为在Linux下一切皆文件,是文件就有执行权限,因此在创建消息队列时要加上执行权限,这里要注意的是0644 这个操作参数不受umask的影响。因此你设置的是多少,得到的操作权限就是多少。

消息队列的发送和接受

值得注意的是,不管是接受消息队列还是在发送消息队列时,都需要用户自己定义一个结构体,用来存储数据,并作为函数参数传入。结构体如下(由自己定义):

struct msgbuf{
    long mtype;
    char mtext[1];
}

这个结构体存在两个成员,一个是long型的变量,表示该消息的类型,因为消息队列的特性,在发送或者接受消息是要明确消息的类型,这样在就可以指定的读取某一个或者或者某一类的消息,同时可以改变消息接受的优先级。

至于为什么需要这个数据结构,是因为消息队列是面向数据块的,读取数据和发送数据都是以结构体的形式进行传递,因此需要我们自己定义数据结构,面向数据块也是消息队列的一个重要特性。

  • 发送消息

向消息队列中添加数据,使用到的是msgsnd()函数,函数原型如下:

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

总共有4个参数,首先要有一个msqid即消息队列的id,通过msgget(key, 0)可以得到;第二个参数便是我们定义的结构体,要将地址传递过去;第三个参数是发送数据的大小,即struct msgbuf结构体中mtext的大小,不包括数据的类型;最后一个参数并不重要,我们可以不必了解,在使用时一律填0即可。

我们在发送数据时要将数据的类型填入mtype,将数据填入mtext,然后这个结构体作为参数传入消息队列,这样便可以实现数据的优先级接受。

  • 接受消息

从消息队列中读取消息,我们使用msgrcv()函数,函数原型如下:

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);

msgrcv()函数有5个参数,比msgsnd()函数多了一个参数,即第4个参数数据类型,因为发送消息时,数据的类型在结构体中保存着,因此不需要再次传入,可是在读消息时我们需要读取特定类型的消息,因此我们要将指定的数据类型作为参数传入。以满足我们的优先级读取。当msgtyp==0时即按照先进先出的顺序读取当前消息队列中第一个消息。

  • 注意点

    1. msgsnd函数的返回值:成功返回0,失败返回-1;

    2. msgrv 函数的返回值:成功返回读取的数据大小,失败返回-1

    3. 数据队列有三个上限:每个数据最大长度上限(MSGMAX),每个数据队列的总字节数上限(MSGMNB),系统上消息队列的总数的上限(MSGMNI)。

      每个数据最大长度上限(MSGMAX)        /proc/sys/kernel/msgmax
      
      每个数据队列的总字节数上限(MSGMNB)   /proc/sy/kernel/msgmnb      
      
      系统上消息队列的总数的上限(MSGMNI)   /proc/sys/kernel/msgmni 
      

消息队列的销毁

通过调用 msgctl()函数可以,销毁消息队列。函数原型:

int msgctl(int msqid, int cmd, struct msqid_ds *buf);

函数参数有三个,第一个是打开或者创建消息队列得到的id,第二个是操作数,销毁的操作数为IPC_RMID,第三个操作数我们不关心一般填0。

查看消息队列

我们可以通过 ipcs -q 命令查看已经创建的消息队列,包括他的key值信息,id信息,拥有者信息,文件权限信息,已使用的字节数,和消息条数。

最后我们也可以使用 ipcrm -Q加消息队列的key值,来删除一个消息队列。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值