消息队列的实现方式
消息队列等于是创建一个队列,进程两端可以往里放数据,也可以从其中提出数据,识别方式是通过keyid来识别队列,队列间消息的收放通过massage type识别。
api
1 #include <sys/msg.h>2
2 // 创建或打开消息队列:成功返回队列ID,失败返回-1
int msgget(key_t key, int flag);
3 // 添加消息:成功返回0,失败返回-1
int msgsnd(int msqid, const void *ptr, size_t size, int flag);
4 // 读取消息:成功返回消息数据的长度,失败返回-1
int msgrcv(int msqid, void *ptr, size_t size, long type,int flag);
5 // 控制消息队列:成功返回0,失败返回-1
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
msgget:
在以下两种情况下,msgget将创建一个新的消息队列:
如果没有与键值key相对应的消息队列,并且flag中包含了IPC_CREAT标志位。key参数为IPC_PRIVATE。
创建队列
msgID = msgget(key, IPC_CREAT|0777)
利用返回值来判断是否创建成功
if(msgID == -1)
{
printf("craet queue failed\n");
}
key值的生成
因为msgget的key是此消息队列的标识,而此key是一个十六进制数
可以利用ftok生成此key值
key_t key;
key = ftok(".",'z');
printf("key id = %x",key);
关于ftok的用法:https://blog.csdn.net/Cowena/article/details/48108585
若不用ftok生成key值,可用一个任意的十六进制数来替换key
msgsnd和msgrcv
这两个api控制消息的收发,等于是msgsnd控制消息发送,msgrcv控制消息的接收
先创建一个结构体用于控制message type和内容
//man 手册内容
struct msgbuf {
long mtype; /* message type, must be > 0 */
char mtext[1]; /* message data */
};
msgsnd的用法
1.先创建一个属于msgsnd的结构体
struct msgbuf sendbuf = {888,"send to get"};
2.将其发出
msgsnd(msgID,&sendbuf,strlen(sendbuf.mtext),0);
msgrcv的用法
1.创建msgrcv的机构体
struct msgbuf readbuf;
2.接收msgsnd发出的消息
msgrcv(msgID,&readbuf,sizeof(readbuf.mtext),888,0);
对应点
msgsnd中的struct中的type定义了此消息的序号,等于为此条消息命名
msgrcv中的long type对应struct中的type,若相同,则发送和接收对应
msgctl的用法(讲一种)
msgget在没有消息队列时会创建消息队列。但是当消息队列多了之后,内存会不断占用。
利用msgctl的操作之一可以删除已创建的msgID
msgctl(msgID,IPC_RMID,NULL);
代码实现
双端发送和接收
第一个端
第二个端