====== python 协程 coroutine 生产者-消费者模型图示 ====== 看了廖雪峰老师关于协程的教程,为了便于理解,用 axure 做了以下图示,对于初学者应该更容易理解一些: - 函数是: A调用B B调用A,有统一的出入口。入口是参数,出口是 return 协程不同。 - 协程是:程序A执行过程中暂时中断,把CPU控制权交给 B ,B执行一段后,再切换回A ,A从中断的地方继续执行。 - 相比多线程,协程的优势:程序控制切换,不需要线程切换的开销,不需要锁机制,多cpu 多进程+协程可提供极高的并发性能。 - 协程的实现:Python对协程的支持是通过generator实现的。 - 在generator中,我们不但可以通过for循环来迭代,还可以不断调用next()函数获取由yield语句返回的下一个值。 - 但是Python的yield不但可以返回一个值,它还可以接收调用者发出的参数(通过gen.send())。 >传统的生产者-消费者模型是一个线程写消息,一个线程取消息,通过锁机制控制队列和等待,但一不小心就可能死锁。如果改用协程,生产者生产消息后,直接通过yield跳转到消费者开始执行,待消费者执行完毕后,切换回生产者继续生产,效率极高: [[https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001432090171191d05dae6e129940518d1d6cf6eeaaa969000|参考原文]] 参考代码: def consumer(): r = '' while True: n = yield r if not n: return print('[CONSUMER] Consuming %s...' % n) r = '200 OK' def produce(c): c.send(None) n = 0 while n < 5: n = n + 1 print('[PRODUCER] Producing %s...' % n) r = c.send(n) print('[PRODUCER] Consumer return: %s' % r) c.close() c = consumer() produce(c) 图示: {{ :blog:ease:img1712:conroutine.png?direct&800 |}} - 注意到consumer函数是一个generator,把一个consumer传入produce后: - 首先调用c.send(None)启动生成器; - 然后,一旦生产了东西,通过c.send(n)切换到consumer执行; - consumer通过yield拿到消息,处理,又通过yield把结果传回; - produce拿到consumer处理的结果,继续生产下一条消息; - produce决定不生产了,通过c.close()关闭consumer,整个过程结束。 整个流程无锁,由一个线程执行,produce和consumer协作完成任务,所以称为“协程”,而非线程的抢占式多任务。 {{tag>原创 python}}