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。而且它們對每個數據都有一個最大長度的限制。
消息隊列的優點:
- 消息隊列可以獨立于發送和接受進程存在
- 接收程序可以通過消息類型有選擇地接收數據,而不是像命名管道中那樣,只能默認地接收。