Linux系统编程(七)消息队列
- 一、什么是消息队列
- 二、消息队列内部原理
- 三、实现消息队列的收发
- 1.发送消息队列
- 2.接收消息队列
- 四、消息队列与命名管道的比较
一、什么是消息队列
- 消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法。
- 每个数据块都被认为含有一个类型,接收进程可以独立地接收含有不同类型的数据结构。
- 消息队列也有与管道一样的不足,就是每个数据块的最大长度是有上限的,系统上全体队列的最大总长度也有一个上限
二、消息队列内部原理
消息队列是消息的链表,存放在内核中并由消息队列标识符表示。内核为每个IPC对象维护了一个数据结构structipc_perm,用于标识消息队列,让进程知道当前操作的是哪个消息队列。每一个msgid_ds表示–一个消息队列,并通过msqid ds.msg_ first、 msg_ last维护一个先进先出的msg链表队列,当发送一 一个消息到该消息队列时,把发送的消息构造成一个msg的结构对象,并添加到msqid_ ds.msg. first、 msg. last维护的链表队列
三、实现消息队列的收发
1.发送消息队列
代码如下(示例):
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/msg.h>
#include <errno.h>
#define PUB_MSG_TYPE 10
#define MAX_TEXT 512
typedef struct msg_st
{long int msg_type;char mtext[MAX_TEXT];
}MSG_T;
typedef struct stu_t
{char name[16];char context[16];
}STU_T;int main()
{MSG_T msg;STU_T stu;int msgpid;strcpy(stu.name, "zhangshan");strcpy(stu.context, "hello");msg.msg_type = PUB_MSG_TYPE;//拷贝memcpy(msg.mtext, &stu,sizeof(STU_T));//创建消息队列msgpid=msgget(1111, IPC_CREAT | 0666);if (msgpid < 0){perror("msgget error:");exit(1);}//发送消息队列msgsnd(msgpid, &msg, sizeof(MSG_T), 0);return 0;
}
2.接收消息队列
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/msg.h>
#include <errno.h>
#include <iostream>
using namespace std;
#define PUB_MSG_TYPE 10
#define MAX_TEXT 512
typedef struct msg_st
{long int msg_type;char mtext[513];
}MSG_T;
typedef struct stu_t
{char name[16];char context[16];
}STU_T;int main()
{MSG_T msg;STU_T stu;int msgpid;//创建消息队列msgpid = msgget(1111, IPC_CREAT | 0666);if (msgpid < 0){perror("msgget error:");exit(1);}//接收消息队列msgrcv(msgpid, &msg,sizeof(MSG_T), PUB_MSG_TYPE,0);memcpy(&stu, &msg.mtext, sizeof(STU_T));cout << "msgtype = " << msg.msg_type << " , name = " << stu.name<<" : "<<stu.context;return 0;
}
四、消息队列与命名管道的比较
消息队列跟命名管道有不少的相同之处,通过与命名管道一样,消息队列进行通信的进程可以是不相关的进程,同时它们都是通过发送和接收的方式来传递数据的。在命名管道中,发送数据用write,接收数据用read,则在消息队列中,发送数据用msgsnd,接收数据用msgrcv。而且它们对每个数据都有一个最大长度的限制。
消息队列的优点:
- 消息队列可以独立于发送和接受进程存在
- 接收程序可以通过消息类型有选择地接收数据,而不是像命名管道中那样,只能默认地接收。