消息队列,是消息的链表,存放在内核中。一个消息队列由一个标识符(即队列ID)来标识
特点:
消息队列是面向记录的,其中的消息具有特点的格式以及特点的优先级。
消息队列独立于发送与接收进程。进程终止时,消息队列及其内容并不会被删除。
消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取。
原型:
#include <sys/msg.h>
// 创建或打开消息对了;成功返回队列ID,失败返回-1
int msgget(key_t key, int flag);
// 添加或发送消息;成功返回消息数据的长度,失败返回-1
int msgsnd(int msqid, const void *ptr, size_t size, int flg);
//读取消息;成功返回消息数据的长度,失败返回-1
int msgrcv(int msqid, void *ptr, size_t size, long type, int flg);
// 控制消息队列;成功返回0,失败返回-1
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
在下面两种情况下,msgget将创建一个新的消息队列:
如果没有与键值key相对应的消息队列,并且flag中包含了IPC_CREAT标志位。
key参数为IPC_PRIVATE。
函数msgrcv在读取消息队列时,type参数有下面几种情况:
type = 0, 返回队列中的第一个消息
type > 0, 返回队列中消息类型为type的第一个消息
type < 0, 返回队列中消息类型值小于或等于type 绝对值的消息,如果有多个,则取类型值最小的消息。
下面实现双方的收发
get.c
#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()
{
struct msgbuf readBuf;
key_t key;
key = ftok(".", 'z');
printf("key=%x\n",key);
int msgId = msgget(key, IPC_CREAT|0777);
if(msgId == -1){
printf("get que failluer\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;
}
send.c
#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()
{
struct msgbuf sendBuf = {888, "this is message from que"};
struct msgbuf readBuf;
memset(&readBuf,0,sizeof(struct msgbuf));
key_t key;
key = ftok(".", 'z');
printf("key=%x\n",key);
int msgId = msgget(key, IPC_CREAT|0777);
if(msgId == -1){
printf("get que failluer\n");
}
msgsnd(msgId, &sendBuf, strlen(sendBuf.mtext), 0);
msgrcv(msgId, &readBuf, sizeof(readBuf.mtext), 988, 0);
printf("read from get: %s\n", readBuf.mtext);
msgctl(msgId, IPC_RMID, NULL);
return 0;
}