Python之路之协程初认识
协程,又称微线程。与子程序类似,但是又不同于子程序。可以说子程序是协程的一个特例。
协程在执行过程中,可以在子程序某处中断,转而去执行其它子程序,然后在某个时间,再被调用,回到中断处继续执行。
举个栗子:
传统的生产者-消费者模式,一般需要一个线程来写消息,另一个线程来获取消息,再通过锁机制来控制队列和等待,但是不小心的话,就很容易产生死锁。
但是,此时如果使用协程的话,就很容易处理了。生产者生产消息,然后通过yeild语句来中断处理,跳转到消费者去执行,消费者完成操作后,再调用生产者继续生产,效率极高。
先看代码示例:
def consumer(): r = '' while True: n = yield r if not n: return print('消费者在消费 %s...' % n) r = 'Success' def produce(c): c.send(None) n = 0 while n < 5: n = n + 1 print('生产者在生产 %s...' % n) r = c.send(n) print('消费者返回状态: %s' % r) c.close() c = consumer() produce(c)
执行结果:
生产者在生产 1... 消费者在消费 1... 消费者返回状态: Success 生产者在生产 2... 消费者在消费 2... 消费者返回状态: Success 生产者在生产 3... 消费者在消费 3... 消费者返回状态: Success 生产者在生产 4... 消费者在消费 4... 消费者返回状态: Success 生产者在生产 5... 消费者在消费 5... 消费者返回状态: Success
解析:
1.send()是生成器generator的一个方法,也就是说consumer是一个generator,在把一个consumer传入produce之后;
2.c.send(None)调用生成器,进入consumer;
3.在consumer中,执行到yeild语句后,会跳出生成器consumer,重新进入produce;
4.在produce中,从n = 0语句继续执行;
5.当执行到c.send(n)后(第一次进入,n = 1,循环后累加),再次进入consumer;
6.此时回到consumer,从之前中断的yeild语句后继续执行,consumer得到生产者传回的1后赋值给n,继续向下执行,然后到下一次循环的yeild语句后中断,再次跳回produce;
7.produce会在r = c.send(n)拿到consumer返回的状态,即r = 'Success',然后继续执行;
8.然后produce进入下一个循环,则重复上面的5~7操作;
9.最后produce不生产了,则通过c.close()关闭consumer,程序结束。
补充:
yeild语句特点:程序执行过程中,遇到yeild语句,会自动中断,在下次调用该方法后,从上次中断的yeild语句处继续向下执行
根据廖雪峰老师的讲解,做了个人理解与总结。相关链接: https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001432090171191d05dae6e129940518d1d6cf6eeaaa969000