概述
什么是消息队列:
消息队列是用链式队列的数据结构来实现的进程间通信方式,数据具有先入先出的特点。
消息队列由ID来进行标识,每一个消息队列的ID都是唯一的。
相关函数
1、打开/创建消息队列
int msgget(key_t key, int msgflg);
返回值:成功返回消息队列id,失败返回EOF
key:键值,由ftok生成
msgflg:写入IPC_CREAT|0666
2、发送接收消息
消息格式:
typedef struct mymsg {
long mtype; //消息的类型,为>0的值
char mtext[1]; //消息,不一定为char,可根据需求自行更改
}msgT;
2.1 发送
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
返回值:成功返回0,失败返回-1
msqid:消息队列id
msgp:要通信的消息
msgsz:消息的大小,单位字节。
注意:消息大小不包括消息类型 msgsz=sizeof(msgT)-sizeof(long)
msgflg:标志位,0代表阻塞等待队列,IPC_NOWAIT代表队列满时不阻塞
2.2 接收
ssize_t msgrcv(int msqid, void *msgp,size_t msgsz,long msgtyp,int msgflg);
返回值:成功返回收到的消息长度,失败返回-1
msqid:消息队列id
msgp:要通信的消息
msgsz:消息的大小,单位字节。
注意:消息大小不包括消息类型 msgsz=sizeof(msgT)-sizeof(long)
msgtyp:消息的类型
msgtyp值 | 含义 |
0 | 接收 "全部类型" 的消息 |
>0 | 只接收 "指定的msg_type类型" 的消息 |
<0 | 接收 "类型<=msg_type绝对值" 的消息 |
msgflg:标志位,0代表阻塞等待队列,IPC_NOWAIT代表队列空时不阻塞
3、删除消息队列
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
msqid:消息队列的id
cmd:要执行的操作,写入IPC_RMID
buf:保存或设置消息队列属性的地址,写入NULL即可
示例代码
发送代码:
#include <sys/msg.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
typedef struct mymsg {
long mtype; //消息的类型,为>0的值
int mtext[1]; //消息
}msgT;
int main(){
key_t key;
int msgid;
msgT tMsg = {1,{100}};
//1.生成key
if((key=ftok(".",1))<0){
perror("ftok");
return -1;
}
perror("ftok");
printf("key = %d\n",key);
//2.创建/打开消息队列
if((msgid=msgget(key,IPC_CREAT|0666))<0){
perror("msgget");
return -1;
}
printf("msgid = %d\n",msgid);
//3.发送消息
msgsnd(msgid,&tMsg,sizeof(msgT)-sizeof(long),0);
//4.删除消息队列
return 0;
}
接收代码:
#include <sys/msg.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ipc.h>
typedef struct mymsg {
long mtype; //消息的类型,为>0的值
int mtext[1]; //消息
}msgT;
int main(){
key_t key;
int msgid;
msgT tMsg;
//1.生成key
if((key=ftok(".",1))<0){
perror("ftok");
return -1;
}
perror("ftok");
printf("key = %d\n",key);
//2.创建/打开消息队列
if((msgid=msgget(key,IPC_CREAT|0666))<0){
perror("msgget");
return -1;
}
printf("msgid = %d\n",msgid);
//3.接收消息
msgrcv(msgid,&tMsg,sizeof(msgT)-sizeof(long),0,0);
printf("id=%ld,data=%d\n",tMsg.mtype,tMsg.mtext[0]);
//4.删除消息队列
msgctl(msgid,IPC_RMID,NULL);
return 0;
}