消息队列概念
消息队列是 IPC(进程间通信, inter process communication)中常用的一种方式, 相比与其他的通信方式消息队列具有在短消息处理和消息类别上有突出的表现. 在理解消息队列前, 需要了解一点关于 Linux 内核的知识.
如图所示, Linux/unix 的体系架构可以抽像成三层结构: 应用程序 (用户程序, 软件等), 内核(用于操作底层硬件) 以及硬件. 所以用户编写的程序是不能够直接操纵底层硬件的, 需要通过系统内核. 因此这就可以解释为什么共享内存的方式是 IPC 最快的方式, 因为共享内存没有在内核中, 而其他的包括消息队列是在内核中开辟空间, 所以在访问速度上直接访问用户内存比内核空间要快.
1.1 消息队列结构
消息队列虽然不能够进程大量数据通信, 但是却有一个很明显的优点, 那就是在同一个消息队列中可以包含不同类型的消息, 接收端可以根据自己的情况接受相应的消息, 那么消息队列是怎样来保证这样的特点的呢? 先看一下它的结构:
如图在消息队列其实就是一个链表, 其中可以存在不同的 type, 每一个 type 可能会有多条消息, 接受端根据自己需要的 type, 一次从链表中获取第一个, 第二个消息.
1.2 如何使用消息队列
消息队列的使用很简单, 使用 msgget( ), msgsnd( ),msgrcv( )以及 msgctl( )就完全搞定.
flag:msgget(key, IPC_CREAT|0666); 创建由 key 指定的消息队列, 操作权限为 0666.
IPC_CREAT: 用来创建一个消息队列
IPC_EXCL: 查询消息队列是否存在, IPC_CREAT 同时使用, 存在则报错.
IPC_NOWAIT: 之后的消息队列操作都为非阻塞
msqid:msgget 创建队列后返回的消息队列唯一的标识.
ptr: 用于接受或发送消息的内容, 其结构固定,
struct msgbuf { long mtype;// 消息类型 char mtext[1024];// 消息数据};
nbytes: 消息长度.
flag: 标志选项
0 阻塞等待
IPC_NOWAIT 使操作不阻塞, 没有消息返回 - 1,error 设置为 ENOMSG
消息队列的 demo
消息队列如何使用? 一个简单的例子:
发送端:
接受端:
消息队列的进阶
在使用消息队列的时候, 你是否会有这样的疑问: 如果多个进程同时向一个消息队列里面同一个 Type 发送消息, 那么是否会出现资源竞争同步的问题呢?
是否会出现上面图中的局面呢, 也就是说多个进程同时往消息队列里面写, 那么就会同时认为 msg1 是链表的末尾, 于是都把自己的消息添加到 msg1 的后面, 导致了上面的现象, 在接收端取数据的时候就会出现问题了.
正确答案是, 系统并没有这么傻, 对于消息队列而言, 一定要保证单链表, 在内核代码中其实是做了同步的, 也就是说当多个进程同时写的话, 内核里面也会一个一个的进行链表的连接. 我们大可放心, 且不像共享内存一样需要用户自己同步, 在使用消息队列的时候用户不需要进行同步.
内核代码里面有一个 ipc_lock_check()来进行同步, 保证资源竞争.
Linux 下的多进程编程
排序 - 冒泡排序
网络流媒体 - RTP 与 RTCP
专注音视频技术,
编程语言学习笔记以及互联网信息分享与交流,
来源: http://www.jianshu.com/p/9351878be73b