0%

python设计模式--生产者消费者模式

1. 生产者消费者模式

生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。

生产者和消费者之间不直接通讯, 而是通过阻塞队列来进行通讯。

生产者生产完数据之后不用等待消费者处理, 直接扔给阻塞队列, 同理, 消费者也不找生产者要数据, 而是直接从阻塞队列中获取。

这里, 阻塞队列可以看做是一个缓冲区, 平衡了生产者和消费者的处理能力。

image-20221222173718064

2. 主要作用

  • 解耦合
  • 异步执行,提高程序的运行效率。

3. 结构剖析

在生产者-消费者模式中,通常有两类线程,一类是生产者线程一类是消费者线程。生产者线程负责提交用户请求,消费者线程则负责处理生产者提交的任务。

​ 最简单粗暴的做法就是生产者每提交一个任务,消费者就立即处理,直到所有任务处理完。但是这样直接通信很容易出现性能上的问题,消费者必须等待它的生产者提交到任务才能执行,就不能达到真正的并行。同时生产者和消费者之间存在依赖关系,在设计上耦合度非常高,这是不可取的。那么最好的做法就是加一个中间层作为通信桥梁

生产者和消费者之间通过共享内存缓存区进行通信。多个生产者线程将任务提交给共享内存缓存区,消费者线程并不直接与生产者线程通信,而在共享内存缓冲区获取任务,并行地处理。其中内存缓冲区的主要功能是数据再多线程间的共享,同时还可以通过该缓存区,缓解生产者和消费者间的性能差。它是生产者消费者模式的核心组件,既能作为通信的桥梁,又能避免两者直接通信,从而将生产者和消费者进行解耦。生产者不需要消费者的存在,消费者也不需要知道生产者的存在。

例如在CV中, 取图线程(进程)通常比较快速, 计算线程(进程)通常较慢, 此时可以维护一个队列(共享内存缓冲区),设计为生产者消费者模式进行处理, 一个取图线程当做生产者, 多个计算线程当做消费者。

4. code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import threading
import queue
import time
#定义一个生产者
def producer():
count = 0
for i in range(5):
print('生产第%s个产品......',count)
q.put(count)
count+=1
time.sleep(1)
q.join()

#定义一个消费者
def consumer(name):
while True:
print("%s 消费第%s个产品" % (name,q.get()))
q.task_done()

print('消费者执行完了所有任务')
#定义一个队列
q = queue.Queue(maxsize=4)

t1 = threading.Thread(target=producer)
t2 = threading.Thread(target=consumer,args=('Consumer',))
t1.start()
t2.start()

'''
生产第%s个产品...... 0
Consumer 消费第0个产品
消费者执行完了所有任务
生产第%s个产品...... 1
Consumer 消费第1个产品
消费者执行完了所有任务
生产第%s个产品...... 2
Consumer 消费第2个产品
消费者执行完了所有任务
生产第%s个产品...... 3
Consumer 消费第3个产品
消费者执行完了所有任务
生产第%s个产品...... 4
Consumer 消费第4个产品
消费者执行完了所有任务
'''