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

posted @ 2018-07-25 16:45  風的季節丶  阅读(168)  评论(0编辑  收藏  举报