消息队列:消息队列是消息的链接表,存放在内核中,一个消息队列由一个标识符(队列ID)来标识
1、消息队列是面向记录的,其中的消息具有特定的格式以及特定的优先级
2、消息队列独立于发送与接收进程,进程终止时,消息队列中的内容不会被删除
3、消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按照消息的类型读取
函数原型:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
//创建/打开消息队列 成功返回队列ID,失败返回-1
int msgget(key_t key, int msgflg);
//添加消息,成功返回0,失败返回-1
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
//读取消息,成功返回消息数据的长度,失败返回-1
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
//控制消息队列
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
创建/打开消息队列: 在这2种情况下会创建一个新的消息队列:
//如果没有与键值 key 相对应的消息队列,并且 flag 中包含了 IPC_CREAT标志
int msgget(key, IPC_CREAT);
//2,key的参数为IPC_PRIVATE
int msgget(key, IPC_PRIVATE);
添加/发送 消息: msqid:消息队列的ID
msgp:向队列中写入的数据,指向消息缓冲区(结构体)的指针,此位置用来暂时存储发送和接收的消息,是一个用户可定义的结构体 msgsz:数据的长度
msgflg:0表示忽略,表示进程将被堵塞,直到进程从队列中得到消息为止,(还有其他形式)
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);//函数原型
//msgp的结构体
struct msgbuf{
long mtype;//消息类型(>0)
char mtext[128];//消息文本
};
读取/接收 消息: msqid:消息队列的ID
msgp:写入的数据,指向消息缓冲区(结构体)的指针 msgtyp:
msgtyp等于0,则返回队列的最早的一个消息。
msgtyp大于0,则返回其类型为msgtyp的第一个消息
msgtyp小于0,则返回其类型小于或等于mtype参数的绝对值的最小的一个消息。
可以看出,type值非 0 时用于以非先进先出次序读消息。也可以把 type 看做优先级的权值。
msgsz:数据的长度 msgflg:0表示忽略,表示进程将被堵塞,直到进程从队列中得到消息为止
//函数原型
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
//msgp结构体
struct msgbuf{
long mtype;//消息类型(>0)
char mtext[128];//消息文本
};
函数例子:消息队列进行2方数据交互 编译时会阻塞到这里
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <string.h>
struct msgbuf{
long mtype; //表示消息类型
char mtext[128]; //存数据
};
int main()
{
struct msgbuf readBuf; //接收消息
struct msgbuf writeBuf = {988,"think you"}; //发送的消息
int msgId = msgget(0x1234,IPC_CREAT | 0777); //创建队列
if(msgId == -1){
printf("failuer\n");
}
msgrcv(msgId,&readBuf,sizeof(readBuf.mtext),888,0); //读消息
printf("%s\n",readBuf.mtext);
msgsnd(msgId,&writeBuf,strlen(writeBuf.mtext),0); //向队列发送数据
msgctl(msgId,IPC_RMID,NULL); //将队列从系统内核中删除
return 0;
}
运行下面程序后会将上面程序解除阻塞,双方实现通信发送信息
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <string.h>
struct msgbuf{
long mtype;
char mtext[128];
};
int main()
{
struct msgbuf writeBuf = {888,"hello world"}; //用来发送消息
struct msgbuf readBuf; //用来接收消息
int msgId = msgget(0x1234,IPC_CREAT | 0777); //打开创建队列,0x1234表示索引节点号写死了的,0777表示权限
if(msgId == -1){
printf("failuer\n");
}
msgsnd(msgId,&writeBuf,strlen(writeBuf.mtext),0); //发送消息
msgrcv(msgId,&readBuf,sizeof(readBuf.mtext),988,0);//读队列中的消息,988表示类型,0表示以默认的方式读数据
printf("%s\n",readBuf.mtext); //读出来打印
msgctl(msgId,IPC_RMID,NULL); //将队列从系统内核中删除
return 0;
}