消息队列

概述

消息队列提供了一种在两个不相关的进程之间传递数据的简单高效的方法,其特点例如以下:

1)消息队列能够实现消息的随机查询。消息不一定要以先进先出的次序读取,编程时能够按消息的类型读取。

2)消息队列同意一个或多个进程向它写入或者读取消息。

3)与无名管道、命名管道一样,从消息队列中读出消息,消息队列中相应的数据都会被删除。

4)每一个消息队列都有消息队列标识符。消息队列的标识符在整个系统中是唯一的。

5)消息队列是消息的链表,存放在内存中,由内核维护。仅仅有内核重新启动或人工删除消息队列时,该消息队列才会被删除。

若不人工删除消息队列,消息队列会一直存在于系统中。


消息队列经常使用操作函数例如以下:

  1. #include <sys/msg.h>  
  2. #include <sys/types.h>  
  3. #include <sys/ipc.h>  
  4.   
  5. key_t ftok(const char *pathname, int proj_id);  
  6. int msgget(key_t key, int msgflg);  
  7. int msgrcv(int msqid, void *msg_ptr, size_t msg_sz, long int msgtype, int msgflg);  
  8. int msgsnd(int msqid, const void *msg_ptr, size_t msg_sz, int msgflg);  
  9. int msgctl(int msqid, int cmd, struct msqid_ds *buf);  

对于消息队列的操作,我们能够类比为这么一个过程:假如 A 有个东西要给 B。由于某些原因 A 不能当面直接给 B。这时候他们须要借助第三方托管(如银行)。A 找到某个详细地址的建设银行,然后把东西放到某个保险柜里(如 1 号保险柜),对于 B 而言,要想成功取出 A 的东西,必须保证去同一地址的同一间银行取东西。并且仅仅有 1 号保险柜的东西才是 A 给自己的。


对于上面的样例。涉及到几个比較重要的信息:地址、银行、保险柜号码

仅仅有同一个地址才干保证是同一个银行,仅仅有是同一个银行两方才干借助它来托管,仅仅有同一个保险柜号码才干保证是对方托管给自己的东西。


而在消息队列操作中。键(key)值相当于地址,消息队列标示符相当于详细的某个银行,消息类型相当于保险柜号码。

同一个键(key)值能够保证是同一个消息队列,同一个消息队列标示符才干保证不同的进程能够相互通信,同一个消息类型才干保证某个进程取出是对方的信息。


键(key)值

System V 提供的进程间通信机制须要一个 key 值。通过 key 值就可在系统内获得一个唯一的消息队列标识符。key 值能够是人为指定的,也能够通过 ftok() 函数获得。


须要的头文件:

#include <sys/types.h>
#include <sys/ipc.h>


key_t ftok(const char *pathname, int proj_id);

功能:

获取键(key)值

參数:

pathname: 路径名

proj_id: 项目ID。非 0 整数(仅仅有低 8 位有效)

返回值:

成功:key 值

失败:-1


消息队列的创建

所需头文件:

#include <sys/msg.h>


int msgget(key_t key, int msgflg);

功能:

创建一个新的或打开一个已经存在的消息队列。

不同的进程调用此函数,仅仅要用同样的 key 值就能得到同一个消息队列的标识符。

參数:

key: ftok() 返回的 key 值

msgflg: 标识函数的行为及消息队列的权限,其取值例如以下:

IPC_CREAT:创建消息队列。

IPC_EXCL: 检測消息队列是否存在。

位或权限位:消息队列位或权限位后能够设置消息队列的訪问权限。格式和open() 函数的 mode_t 一样(open() 的使用请点此链接),但可运行权限未使用。

返回值:

成功:消息队列的标识符

失败:-1


演示样例代码例如以下: