这里利用了Python生成器的send()方法来实现生产者与消费者之间的通信,非常巧妙!
还不了解send()方法的请移步我的上一篇博文:https://blog.csdn.net/weixin_42471384/article/details/82624009
实例:
def producer(c):
# 生产者产生消息,之后,yield到消费者执行
c.send(None) # 首先调用c.send(None)启动生成器
n = 0
while n < 5:
n = n + 1
print("[生产者] 正在生产 %s..." % n)
r = c.send(n) # 一旦生产了东西,通过c.send(n)切换到consumer执行
print("[生产者] 消费者 return: %s" % r)
c.close()
def consumer():
r = ''
while True:
n = yield r
if not n:
return
print('[消费者] 正在消费 %s...' % n)
r = '200 OK'
c = consumer() # 生成器对象
producer(c) # 生成器对象传入producer()函数
代码解读:
1.c = consumer(),不是调用函数def consumer(),而是声明一个生成器对象
2.producer(c),将生成器对象传入函数def producer()
3.此时,执行流程跑到:c.send(None),相当于c.__next__()方法,
此时,执行流程跑到:def consumer(),遇到yield,返回结果 ''。
4.此时,执行流程跑回:c.send(None),继续往下执行,n=0,
由于n = 0,符合判断条件,print("[生产者] 正在生产 %s..." % n),
就是输出结果中的第一条:[生产者] 正在生产 1...
往下继续执行,r = c.send(n),此时n = 1,
此时,执行流程跑到:def consumer(),由于生成器会记录上一次yield的状态,
所以此时,def consumer()的 n = yield r 变为 n = send(1),即:n = 1,
进入判断条件:if not n:,不符合,所以print([消费者] 正在消费 %s...' % n),
就是输出结果中的第二条:[消费者] 正在消费 1...
此时,执行流程跑回:def producer(c)中的print("[生产者] 消费者 return: %s" % r)
就是输出结果的第三条:[生产者] 消费者 return: 200 OK
5.之后的流程继续按照上面的步骤执行,直到produce决定不生产了,通过c.close()关闭consumer,整个过程结束。
结束语:
整个流程无锁,由一个线程执行,produce和consumer协作完成任务,所以称为“协程”,而非线程的抢占式多任务。
本文借鉴:
https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001432090171191d05dae6e129940518d1d6cf6eeaaa969000#0