消息队列,是消息的链接表,存放在内核中。一个消息队列由一个标识符(即队列ID) 来标识
1、特点
(1)消息队列是面向记录的,其中的消息具有特定的格式以及特定的优先级
(2)消息队列独立于发送与接收进程。进程终止时,消息队列及其内容并不会被删除.
(3)消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取。
2、函数原型
头文件:
#include<sys/ipc.h>
#include<sys/types .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
int msgrev (int msqid, void *otr, eize : size, long type,int flag)!
// 控制消息队列: 成功返回0,失败返回-1
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
在以下两种情况下,msgget将创建一个新的消息队列:
(1) 如果没有与键值key相对应的消息队列,并且flag中包含了IPC_CREAT标志位
(2) key参数为IPC PRIVATE。
函数msgrcv在读取消息队列时,type参数有下面几种情况
(1) type == 0,返回队列中的第一个消息
(2) type >0,返回队列中消息类型为 type 的第一个消息
(3) type<0,返回队列中消息类型值小于或等于 type 绝对值的消息,如果有多个,则取类型值最小的消息。.
可以看出,type值非0时用于以非先进先出次序读消息。也可以把 type 看做优先级的权值
系统立IPC通讯(消息队列、信号量和共享内存) 时必须指定一个ID。适常情况下,该id值过ftok函数得到
ftok原型
头文件
#include <sys/types.h>
#include <sysipc.h>
函数原型:
key_t ftok( const char * fname, int id )
fname就是你指定的文件名《已经存在的文件名》,一般使用当前目录,如:
key_t key;
key = ftok(".",1); 这样就是将fname设为当前目录。
封装接收消息代码:
#include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <string.h> // int msgget(key_t key, int msgflg); // int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); // ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, // int msgflg); struct msgbuf { long mtype; /* message type, must be > 0 */ char mtext[256]; /* message data */ }; int main() { //1.huoqu struct msgbuf readBuf; key_t key; key = ftok(".",'m'); printf("key=%x\n",key); int msgId = msgget(key, IPC_CREAT|0777); if(msgId == -1 ){ printf("get que failuer\n"); } memset(&readBuf,0,sizeof(struct msgbuf)); msgrcv(msgId, &readBuf,sizeof(readBuf.mtext),888,0); printf("read from que:%s\n",readBuf.mtext); struct msgbuf sendBuf = {988,"thank you for reach"}; msgsnd(msgId,&sendBuf,strlen(sendBuf.mtext),0); msgctl(msgId,IPC_RMID,NULL); return 0; }
封装发送消息代码:
#include <stdio.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <string.h> // int msgget(key_t key, int msgflg); // int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); // ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, // int msgflg); struct msgbuf { long mtype; /* message type, must be > 0 */ char mtext[256]; /* message data */ }; int main() { //1.huoqu struct msgbuf sendBuf = {888,"this is message from quen"}; struct msgbuf readBuf; memset(&readBuf,0,sizeof(struct msgbuf)); key_t key; key = ftok(".",'m'); printf("key=%x\n",key); int msgId = msgget(key, IPC_CREAT|0777); if(msgId == -1 ){ printf("get que failuer\n"); } msgsnd(msgId,&sendBuf,strlen(sendBuf.mtext),0); printf("send over\n"); msgrcv(msgId, &readBuf,sizeof(readBuf.mtext),988,0); printf("return from get:%s\n",readBuf.mtext); msgctl(msgId,IPC_RMID,NULL); return 0; }
编译结果: