消息队列提供了一种在两个不相关的进程之间传递数据的简单高效的方法,其特点如下:
消息队列常用操作函数如下:
对于消息队列的操作,我们可以类比为这么一个过程
:假如 A 有个东西要给 B,因为某些原因 A 不能当面直接给 B,这时候他们需要借助第三方托管(如银行),A 找到某个具体地址的建设银行,然后把东西放到某个保险柜里(如 1 号保险柜),对于 B 而言,要想成功取出 A 的东西,必须保证去同一地址的同一间银行取东西,而且只有 1 号保险柜的东西才是 A 给自己的。
对于上面的例子,涉及到几个比较重要的信息:地址、银行、保险柜号码
。
只有同一个地址才能保证是同一个银行,只有是同一个银行双方才能借助它来托管,只有同一个保险柜号码才能保证是对方托管给自己的东西。
而在消息队列操作中,键(key)值
相当于地址,消息队列标示符
相当于具体的某个银行
,消息类型
相当于保险柜号码。
同一个键(key)值
可以保证是同一个消息队列,同一个消息队列标示符
才能保证不同的进程可以相互通信,同一个消息类型
才能保证某个进程取出是对方的信息。
System V 提供的进程间通信机制需要一个 key 值,通过 key 值就可在系统内获得一个唯一的消息队列标识符。key 值可以是人为指定的,也可以通过 ftok() 函数获得。
需要的头文件:
功能:
参数:
返回值:
所需头文件:
功能:
参数:
返回值:
示例代码如下:
运行结果如下:
对于消息队列的读写,都是以消息类型为准。消息类型相当于保险柜号码
,A 往 1 号保险柜放东西,对方想取出 A 的东西必须也是从 1 号保险柜里取。同理,某一进程往消息队列添加 a 类型的消息,别的进程要想取出这进程添加的信息也必须取 a 类型的消息。
在学习消息队列读写操作前,我们先学习消息队列的消息格式:
消息类型必须是长整型的,而且必须是结构体类型的第一个成员
,类型下面是消息正文,正文可以有多个成员(正文成员可以是任意数据类型的)。至于这个结构体类型叫什么名字,里面成员叫什么名字,自行定义,没有明文规定。
所需头文件:
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 )
功能:
参数:
返回值:
所需头文件:
int msgctl(int msqid, int cmd, struct msqid_ds *buf)
功能:
参数:
返回值:
写端示例代码如下:
读端示例代码如下:
运行结果如下: