关键词:C++ 线程间通信 消息中间件 C++11标准库 boost
引子
为什么使用多线程?线程间为何需要通信?
通常认为,存在多个任务,则需要创建多线程。这种说法太过于笼统,很难让人理解到精要,有一种豁然开朗的感觉。又或者说,对于更高级别的并发,处理器以及计算机特性没有更为是深入的理解。或者说,没有说明多线程的关键作用。
那么,引入一个多线程中的重要概念:多线程用来平衡不同任务负载。
计算机的处理器的每一项工作所占用的资源是不同的。比如搬运数据,使用DMA操作,可以无需占用处理器。比如中断资源和正常任务运行,中断往往是珍贵的、稀缺的,不能在中断里处理复杂任务,以免影响下一次的中断。而非紧急响应的任务,则可以移步到普通任务去执行。
效率增加
我这里引用一个例子,以工厂加工一个产品为例子。加工一个产品需要两道工序。假设工序A需要2小时加工一件,工序B需要5小时加工一件。
如果有一个工人(2个核心),可以同时照顾A与B,那么生产一件需要多久?答案是第一件需要7小时,随后的每一件需要5个小时,这取决于较慢的那个工序。也就是取决于短板。
实际上一个工人(这里指电脑的处理器,通常是多个核心的),可以同时干更多的活。假设这个工人可以兼顾7个流水线(7个核心)。2个工序A流水线,5个工序B流水线。这样是不是产能最大?这样生产一个需要多久,假设工序A生产了很多件作为起始。那么现在开始计算的话,流水线B平均每小时消耗1件,流水线A平均每小时生产1件。那么该产线的效率是1小时每件。
实际计算,核心数由2个增加到了7个,处理器是原来的3.5倍性能提升,效率却是原来的5倍的提升。这就是关键。
为什么?
实际上,我们让需要时间更长的工序不再成为短板,生产者效率等于消费者效率,以便最大化效益。这就是多线程的作用,平衡不同任务间的负载。
生产者1 生产者2 生产者3 生产者4 …… 生产者n | |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| | |
生产者放入 → 仓库 →消费者取出 | |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| | |
消费者1 消费者2 消费者3 消费者4 …… 消费者n |
临时概念
产物(临时概念)
每道工序后的成品,具体指经计算机加工后的信息。
生产者
通俗释义:上一道工序或者任务或者线程。产出一些产物(加工完的信息)。
消费者
通俗释义:下一道工序或者任务或者线程,消费一些产物(待加工的信息)。
邮箱
通俗释义:工序间、任务间、线程间通信的工具,邮箱传递邮件。通常是比较小的产物(加工后的信息的地址)。
消息队列
通俗释义: 一个放产物的空间(仓库),比邮箱大一些的产物(加工后的信息)。
环形缓冲区(临时概念)
通俗释义:还是放产物的空间(仓库),不过是环形的,不会溢出,满了就丢一些。
存储仓库(临时概念)
通俗释义:还是放产物的空间(仓库)。
消息中间件
通俗释义:放产物的,也就是线程间通信工具,以上放产物的这些大大小小仓库的总称。
核心概念
通过以上场景,剔除临时概念用于理解。保留关键部分。
线程范畴
生产线程,消费线程。
消息中间件
邮箱,消息队列。
场景
单片机
数据的中断接收与数据处理操作。
TCP
数据的接收与处理操作。
分布式架构
分布式高并发架构提升响应。
标准库
线程间同步与线程间通信。
c++11 标准库提供的线程间工具有三个。信号量,锁,条件变量。
BOOST
*(待补充)