消息队列(也叫做报文队列)是一个消息的链表。可以把消息看作一个记录,具有特定的格式以及特定的优先级。对消息队列有写权限的进程可以向消息队列中按照一定的规则添加新消息;对消息队列有读权限的进程则可以从消息队列中读走消息。
IPC消息队列资源的限制
IPC消息队列的缺省数为16
每个消息的缺省最大值8192字节
队列中全部信息的缺省大小为16384字节
消息队列的概念和原理
消息队列是一种进程间通信(IPC)的机制,它允许不同进程之间通过消息进行交互。消息队列由内核负责管理,可以按顺序发送消息包(消息类型和消息内容),也可以全双工工作,即同时接收和发送消息。消息队列可以不按消息的顺序接收消息,因此具有一定的灵活性。
消息队列的应用场景
1.进程间通信:消息队列可以用于实现不同进程之间的通信,例如,一个进程需要向另一个进程发送数据或者通知,可以使用消息队列来实现。
2.异步处理:当一个进程需要异步处理某些任务时,可以使用消息队列来实现。例如,一个进程需要等待某个事件发生,它可以通过消息队列发送一个消息,通知另一个进程该事件已经发生。
3.任务分发:在分布式系统中,消息队列可以用于任务分发。例如,一个进程需要将某个任务分发给其他进程,它可以通过消息队列发送任务信息,其他进程收到消息后,可以按照任务要求进行处理。
4.日志记录:消息队列可以用于记录系统日志,当一个进程需要记录日志时,它可以将日志信息发送到消息队列,另一个进程可以实时接收并保存这些日志信息。
消息队列的优缺点
1.优点:
- 消息队列允许不同进程之间进行异步通信,提高了系统的并发性能。
- 消息队列具有一定的可靠性,即使接收进程没有及时处理消息,消息队列仍然可以保存消息。
- 消息队列可以实现进程间的解耦,降低了进程之间的依赖关系。
2.缺点:
- 消息队列的通信效率较低,因为消息需要经过内核的复制和传输。
- 消息队列的实现较为复杂,需要涉及到进程间通信、内存管理等方面的知识。
消息队列模型
操作消息队列
1、 打开或创建消息队列.
2、 读写操作:消息读写操作非常简单,对开发人员来说,每个消息都类似如下的数据结构:
struct msgbuf{
long mtype;
char mtext[1];
};
3、 获得或设置消息队列属性:
消息队列的基本操作—msgget()
ftok函数
key_t ftok( char * fname, int id )
fname指定的文件名(该文件必须是存在而且可以访问的),id是子序号,虽然为int,但是只有8个比特被使用(0-255)。
当成功执行的时候,一个key_t值将会被返回,否则 -1 被返回。
消息队列的基本操作—msgrcv()
msqid:消息队列描述字,描述从哪个消息队列读取消息
msgp:消息存储位置
size:消息内容的长度(mtext[])
type:请求读取的消息类型
消息队列的基本操作—msgrcv()工作流程
flag:规定队列无消息时内核应做的操作
成功返回读出消息的实际字节数,否则返回-1。
取消息的时候并不一定按照先进先出的次序取消息,可以按照消息的类型字段取消息。
消息队列的基本操作—msgsnd()
消息队列的基本操作—msgctl()
•调用返回:成功返回0,否则返回-1。
消息队列使用示例——发送
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
struct msg{
long msg_types;
char msg_buf[512];
};
int main()
{
int qid;
int pid;
int len;
struct msg pmsg;
pmsg.msg_types = getpid();
sprintf(pmsg.msg_buf, "hello!this is:%d\n",getpid());
len = strlen(pmsg.msg_buf);
//key_t key;
//key = ftok(“usr/local/test”, 30);
if((qid = msgget(0x66, IPC_CREAT | 0666))<0)
{
perror("msgget");
exit(1);
}
if((msgsnd(qid, &pmsg, len, 0))<0)
{
perror("msgsnd");
exit(1);
}
printf("successfully send a message to the queue:%d\n", qid);
system("ipcs -q");
return 0;
}
消息队列使用示例——接收
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define BUFSIZE 4096
struct msg{
long msg_types;
char msg_buf[511];
};
int main(int argc, char* argv[])
{
int qid, len;
struct msg pmsg;
qid = msgget(0x66,IPC_CREAT | 0666);
//key_t key;
//key = ftok(“usr/local/test”, 30);
len = msgrcv(qid, &pmsg, BUFSIZE, 0, 0);
if(len > 0){
pmsg.msg_buf[len] = '\0';
printf("recving que id:%ld\n",qid);
printf("message type:%d\n", pmsg.msg_types);
printf("message length:%d\n",len);
printf("message text:%s\n",pmsg.msg_buf);
}else if(len == 0)
printf("no message!");
else{
perror("msgrcv");
exit(0);
}
system("ipcs -q");
exit(0);
}