消息队列,是消息的链接表,存放在内核中。一个消息队列由一个标识符(即队列ID)来标识。
1、特点
-
消息队列是面向记录的,其中的消息具有特定的格式以及特定的优先级。
-
消息队列独立于发送与接收进程。进程终止时,消息队列及其内容并不会被删除。
-
消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取。
2、原型
#include <sys/msg.h>
// 创建或打开消息队列:成功返回队列ID,失败返回-1
int msgget(key_t key, int flag);
// 添加消息:成功返回0,失败返回-1
int msgsnd(int msqid, const void *ptr, size_t size, int flag);
// 读取消息:成功返回消息数据的长度,失败返回-1
int msgrcv(int msqid, void *ptr, size_t size, long type,int flag);
// 控制消息队列:成功返回0,失败返回-1
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
在以下两种情况下,msgget
将创建一个新的消息队列:
- 如果没有与键值key相对应的消息队列,并且flag中包含了
IPC_CREAT
标志位。 - key参数为
IPC_PRIVATE
。
key是一个索引值,通过索引值在linux内核中找到某个队列。
flag是打开队列的方式。
msgsnd(队列ID,消息,消息大小,标志位)
msgrcv(队列ID,放的数据,数据大小,队列类型,标志位)
队列类型:类似于A与B约定好的位置,并在这个位置找到数据。
*buf:通常写NULL;
3.例子
#include<stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
//消息队列结构体
struct msgbuf {
long mtype; /* message type, must be > 0 */
char mtext[128]; /* message data */
};
int main()
{
struct msgbuf sendBuf={888,"this is message from quen"};
struct msgbuf readBuf;
int msgid=msgget(0x1234,IPC_CREAT|0777);//0700可读可写可执行
if(msgid==-1){
printf("creat msg fail\n");
}
msgsnd(msgid,&sendBuf,strlen(sendBuf.mtext),0);
msgrcv(msgid,&readBuf,sizeof(readBuf.mtext),988,0);
printf("read :%s\n",readBuf.mtext);
return 0;
}
#include<stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
//消息队列结构体
struct msgbuf {
long mtype; /* message type, must be > 0 */
char mtext[128]; /* message data */
};
int main()
{
struct msgbuf readBuf;
struct msgbuf sendBuf={988,"thank you"};
int msgid=msgget(0x1234,IPC_CREAT|0777);
if(msgid==-1){
printf("creat msg fail\n");
}
msgrcv(msgid,&readBuf,sizeof(readBuf.mtext),888,0);
msgsnd(msgid,&sendBuf,strlen(sendBuf.mtext),0);
printf("read :%s\n",readBuf.mtext);
return 0;
}
发送消息要与接收消息对应的号一致,如发送888,接收也要888。
运行结果:
4.补充:
#include <sys/types.h>
#include <sys/ipc.h>key_t ftok(const char *pathname, int proj_id);
ftok函数返回一个标识符(即队列ID)。
pathname:文件路径。
proj_id:任何数字/字符 (如'Z')
例子
#include<stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
struct msgbuf {
long mtype; /* message type, must be > 0 */
char mtext[128]; /* message data */
};
int main()
{
struct msgbuf readBuf;
struct msgbuf sendBuf={988,"thank you"};
key_t key;
key=ftok(".",1);
printf("key=%x\n",key);
int msgid=msgget(key,IPC_CREAT|0777);
if(msgid==-1){
printf("creat msg fail\n");
}
msgrcv(msgid,&readBuf,sizeof(readBuf.mtext),888,0);
msgsnd(msgid,&sendBuf,strlen(sendBuf.mtext),0);
printf("read :%s\n",readBuf.mtext);
msgctl(key,IPC_RMID,NULL);
return 0;
}
#include<stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
struct msgbuf {
long mtype; /* message type, must be > 0 */
char mtext[128]; /* message data */
};
int main()
{
struct msgbuf sendBuf={888,"this is message from quen"};
struct msgbuf readBuf;
key_t key;
key=ftok(".",1);
printf("key=%x\n",key);
int msgid=msgget(key,IPC_CREAT|0777);
if(msgid==-1){
printf("creat msg fail\n");
}
msgsnd(msgid,&sendBuf,strlen(sendBuf.mtext),0);
msgrcv(msgid,&readBuf,sizeof(readBuf.mtext),988,0);
printf("read :%s\n",readBuf.mtext);
msgctl(key,IPC_RMID,NULL);
return 0;
}
IPC_RMID:把消息队列的ID从内核取出。
学习笔记,仅供参考