一、生产者消费者模式
生产者消费者模式是一种用于解决多个模块之间数据通信问题的高效机制。通过在数据生产者和数据消费者之间设立数据缓冲区,实现地低耦合度的数据通信。
图1 生产者/消费者模式的结构
这样的一个结构就像是流水线上两道工序和他们之间的货架。前道工序上有若干工人,他们会将本工序的产品放到货架上,而后立即回归到自己的生产工作中;同样地,后道工序上的若干工人们,可以直接从货架上收取上道工序的产品,直接开始自己的生产工作。
相比于直接调用的数据通信方式,生产者/消费者模式虽然多了一个数据缓冲区,但是优势也非常明显:
-
支持模块并发
使用直接调用的通信方式,最明显的弊端就是,调用关系是阻塞的,调用者必须中断自己的任务,等待被调者的返回再继续执行,这样就大大降低了程序运行效率。特别是当被调用的模块中涉及网络通信、文件读写这样的耗时操作时,主调一直在阻塞等待将是不可接受的性能损失。使用生产者/消费者模式,生产者模块(也就是原先的主调函数)只需要将数据放进缓冲区,这一个周期的任务就完成了,它可以立即返回,去执行下一个周期的任务。同样的,消费者模块(对应原先的被调函数)也不必苦苦等待上一个流程的结束,只要数据缓冲区不是空的,他就可以立即开始消费操作。
对应到上面流水线的例子里,直接调用的通信方式好比是前道工序的工人必须苦苦等候隔壁组的兄弟忙完手上的产品,腾出手来接过去自己的完成品;又或者是后道工序的工人要跑到隔壁去打听有没有处理完的产品。无论哪一种情况,都是巨大的效率损失。而中间摆上一个货架,前道工序的工人只需要将产品摆上货架(只要货架不是满的),就可以继续生产,而对于后道工序的工人,只要货架上还有产品,他们就直接可以从上面取出产品进行操作。
-
支持忙闲不均
在很多业务场景中,数据生产者的生产速度和数据消费者的消费速度有可能在一定范围内波动,如果使用直接调用的方式,则无论主调侧还是被调侧进入忙碌状态,两侧都必须将速度减慢,来协调数据同步的速度。而如果通过数据缓冲区进行交互,某一方进入忙碌状态时,可以利用缓冲区中的数据或空间进行调节(如消费者处理速度放缓,则生产者也不必随之减缓速度,产生数据可以