目录
一、消息队列的定义
二、相关函数
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);
}