Linux——消息队列
目录
一、消息队列的定义
二、相关函数
2.1 msgget 函数
2.2 msgsnd 函数
2.3 msgrcv 函数
2.4 msgctl 函数
三、消息队列的操作
3.1 创建消息队列
3.2 获取消息队列并发送消息
3.3 从消息队列接收消息recv
四、 删除消息队列
4.1 ipcrm
4.2 msgctl函数
一、消息队列的定义
消息队列是一种用于在应用程序之间传递和存储数据的通信机制。它允许应用程序将消息发送到队列中,然后由另一个应用程序从队列中接收和处理这些消息。消息队列可以有效地实现异步通信、解耦应用程序之间的依赖关系,以及实现消息的持久化和顺序处理。常见的消息队列系统包括RabbitMQ、Kafka、ActiveMQ等。消息队列在现代分布式系统和微服务架构中被广泛应用。
二、相关函数
2.1 msgget 函数
msgget()创建或者获取一个消息队列
函数模型:
int msgget(key_t key,int msqflg);
函数参数:
1.msqflg: IPC_CREAT
返回值:msgget()成功返回消息队列 ID,失败返回-1
2.2 msgsnd 函数
函数模型:
int msgsnd(int msqid, const void *msqp, size_t msqsz, int msqflg);
msgsnd()发送一条消息,消息结构为:struct msgbuf{long mtype; // 消息类型, 必须大于 0char mtext[1]; // 消息数据}
函数参数:1.msqsz: 指定 mtext 中有效数据的长度2.msqflg:一般设置为 0 可以设置 IPC_NOWAIT返回值:msgsnd()成功返回 0, 失败返回-1
2.3 msgrcv 函数
msgrcv() 接收一条消息
函数模型:
ssize_t msgrcv(int msqid, void *msgp, size_t msqsz, long msqtyp, int msqflg);
函数参数:
1.msqtyp: 指定接收的消息类型,类型可以为 02.msqflg: 一般设置为 0 可以设置 IPC_NOWAIT返回值:msgrcv()成功返回 mtext 中接收到的数据长度, 失败返回-1
2.4 msgctl 函数
msgctl() 控制消息队列
函数模型:
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
函数参数:
cmd: IPC_RMID返回值:
msgctl()成功返回 0,失败返回-1
三、消息队列的操作
3.1 创建消息队列
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/msg.h>int main()
{int msgid=msgget((key_t)1234,IPC_CREAT|0600);if(msgid==-1){printf("msgid err\n");exit(1);}}
通过ipcs 命令查看是否已经创建好了消息队列
3.2 获取消息队列并发送消息
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/msg.h>struct mess
{long type;char buff[32];
};int main()
{int msgid=msgget((key_t)1234,IPC_CREAT|0600);if(msgid==-1){printf("msgid err\n");exit(1);}struct mess dt;dt.type=1;//1类型消息strcpy(dt.buff,"hello1");msgsnd(msgid,(void*)&dt,32,0);}
ipcs -q 只显示消息队列
ipcs -m 只显示共享内存
ipcs -s 只显示信号量
msgsnd 函数 发送消息:
msgsnd(msgid, &dt, 32, 0); 使用 msgsnd 函数向消息队列发送消息。msgid 是之前通msgget 获取的消息队列标识符;
msgid是往哪个消息队列中添加;
&dt 是指向要发送的消息结构体的指针;
32 是要发送的消息数据的长度;
0 是消息发送的标志,这里使用默认值。
3.3 从消息队列接收消息recv
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/msg.h>struct mess
{long type;char buff[32];
};int main()
{int msgid=msgget((key_t)1234,IPC_CREAT|0600);if(msgid==-1){printf("msgid err\n");exit(1);}struct mess dt;msgrcv(msgid,&dt,32,1,0);printf("recv:%s\n",dt.buff);
}
运行此文件,会发现消息队列数会随执行的次数增加而减少
并且运行三次之后消息读完了再运行会堵塞
四、 删除消息队列
4.1 ipcrm
删除消息队列中的消息用 ipcrm -q msqid 的号。
4.2 msgctl函数
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/msg.h>struct mess
{long type; char buff[32];
};int main()
{int msgid = msgget((key_t)1234, IPC_CREAT|0600);if (msgid == -1) {printf("msgget err\n");exit(1);}struct mess dt;msgrcv(msgid, &dt, 32, 2, 0);//意思读2号消息printf("read msg:%s\n", dt.buff);//打印消息msgctl(msgid,IPC_RMID,NULL);
}