生产消费模型初探

什么是生产消费模型

在程序中,一个模块负责产生数据,而将产生的数据交由另一模块(这些模块可以是类、函数、线程、进程···)处理,我们将前者称作生产者,将后者称作消费者,二者之间需要一段存放数据的缓冲区,如图所示:
在这里插入图片描述
如是,抽象出生产消费模型。

以我正在做的一个实时的图像处理为例,整个过程可分为三部分,图像抓取、图像处理、图像呈现。在这个程序中,我做了如图所示的处理:在这里插入图片描述
线程一充当生产者,线程二既是消费者也是生产者(相对于不同缓冲区),线程三充当消费者,两队列即缓冲区。

可是为什么要用这个模型呢,直接将这几个步骤写成简单的顺序结构不行吗?

生产消费模型的优势

  1. 解耦,即减小模块之间的依赖性。在上述例子中,每个线程只需做好自己的“本职工作”对相应的缓冲队列负责即可,线程与线程之间并无直接联系,在这种模块和模块依赖性很弱的情况下,代码修改和重用会成为一个相对简单的事情。
  2. 支持并发。使用了生产者/消费者模式之后,生产者和消费者可以是两个独立的并发主体(就像例子中的多个线程。生产者把制造出来的数据往缓冲区一丢,就可以再去生产下一个数据。基本上不用依赖消费者的处理速度)。如果例子中的步骤顺序实现,当某个模块阻塞(例如图像处理模块需要时间较长),其他模块只能等待,效率不高,更可怕的是,在该程序中图像抓取一旦等待,抓取到的图像就不再连续了。

数据单元

  1. 何为数据单元
    从缓存区拿放数据的基本单位。上例中我将每一帧图片作为一个数据单元。
  2. 数据单元特性
  • 关联到业务对象
  • 完整性:在传输过程中,保证数据单元的完整,不可以部分传递
  • 独立性:各个数据单元之间没有互相依赖,某个数据单元传输失败不会影响已经完成传输的单元和尚未传输的单元。
  • 颗粒性: 可看作是数据单元的大小吧(n个业务对象打包成一个数据单元,n的大小需要综合考量了)

队列缓冲区

//(只叙述线程方式)
在线程方式下,生产者和消费者是不同的线程。生产者把数据写入队列头(push),消费者从队列尾部读出数据( pop)。当队列为空,消费者就等待;当队列满(达到最大长度),生产者就等待。

  • 优点:逻辑清晰、代码简单、维护方便、大部分编程语言都内置了队列的支持 (显然很适合我这种初学者?)(当然这是建立在数据量不大的情况下)
  • 缺点:
    • 频繁地 push、pop,内存分配的开销不小;
    • 同步和互斥的性能开销(标个记,还不是很明白)

(待续——环形缓冲区、双缓冲区······)
(ps:这是一份学习笔记,如有错误,拜托大家不吝指正)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值