在学习进程线程的时候,我们会接触到生产者与消费者模式。那么什么是生产者与消费者模式呢?
首先我们要明白什么是生产者,什么是消费者。
在线程世界里,生产者就是生产数据(或者说发布任务)的线程,消费者就是消费数据(或者说处理任务)的线程。在任务执行过程中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据(也就是消费者轮询)。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者提供更多的任务(也就是生产者阻塞)。
由此产生的生产者和消费者模式,可以通过平衡生产线程和消费线程的工作能力来提高程序整体处理数据的速度。
也就是利用多线程和队列,实现生产者与消费者之间的缓冲区,使
1、解耦
降低消费者和生产者之间的耦合,也就是彼此的直接依赖,以防一方作出更改后影响到另一边的运行。
2、均衡运行
当生产者制造数据快的时候,消费者来不及处理,未处理的数据可以暂时存在缓冲区中,慢慢处理掉。而不至于因为消费者的性能造成数据丢失或影响生产者生产。所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不直接找生产者要数据,而是从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。这样就不会因为彼此的处理速度而发生阻塞。
接下来我们放一个很经典的吃包子程序,来观察生产者和消费者模式的编写。
import queue,threading #导入队列、线程模块
import time
q=queue.Queue(10)
def pro(i):
while 1:
q.put('{}号厨师制作'.format(i)) #往队列中放入内容
print('{}号厨师制作'.format(i))
time.sleep(1) #这里可以使用time模块的sleep函数,使运行速度变慢,便于观察
def cus(i):
while 1:
ret=q.get() #取出
print('顾客{}正在吃{}的包子'.format(i,ret))
time.sleep(2)
if __name__ == '__main__':
for i in range(1,4): #创建3个厨师
p1=threading.Thread(target=pro,args=str(i))
p1.start()
for i in range(1,3): #创建2个顾客
p2=threading.Thread(target=cus,args=str(i))
p2.start()
运行时,三个厨师和两个顾客的线程并发,显然厨师的生产速度快于顾客吃包子的速度。因此,厨师生产出的包子就会先堆放在队列中(队列设定了最大存放数10),直到顾客从队列中取出包子再生产。
>>>
1号厨师制作
2号厨师制作
3号厨师制作
顾客1正在吃1号厨师制作的包子
顾客2正在吃2号厨师制作的包子
2号厨师制作
1号厨师制作
3号厨师制作
2号厨师制作
顾客1正在吃3号厨师制作的包子
3号厨师制作
1号厨师制作
参考文献:
http://python.jobbole.com/87592/
http://www.liujiangblog.com/course/python/80