美文网首页
知识点2-协程

知识点2-协程

作者: 二十二_0cbe | 来源:发表于2019-08-09 15:19 被阅读0次
    1. 什么是协程?
    • 协程,英文Coroutines,是一种比线程更加轻量级的存在。正如一个进程可以拥有多个线程一样,一个线程也可以拥有多个协程。
    • 协程不是被操作系统内核所管理,而完全是由程序所控制(也就是在用户态执行)。这样带来的好处就是性能得到了很大的提升,不会像线程切换那样消耗资源。
    • 协程的开销远远小于线程的开销。
    1. 与多线程比,协程有何优势?
    • 最大的优势就是协程极高的执行效率。因为子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优势就越明显。
    • 第二大优势就是不需要多线程的锁机制,因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断状态就好了,所以执行效率比多线程高很多。
    1. 协程是一个线程执行,那怎么利用多核CPU呢?

    最简单的方法是多进程+协程,既充分利用多核,又充分发挥协程的高效率,可获得极高的性能。

    1. 消费者问题

    Python对协程的支持还非常有限,用在generator中的yield可以一定程度上实现协程。虽然支持不完全,但已经可以发挥相当大的威力了。
    传统的生产者-消费者模型是一个线程写消息,一个线程取消息,通过锁机制控制队列和等待,但一不小心就可能死锁。如果改用协程,生产者生产消息后,直接通过yield跳转到消费者开始执行,待消费者执行完毕后,切换回生产者继续生产,效率极高:

    import time
    
    def consumer():
        r = ''
        while True:
            n = yield r
            if not n:
                return
            print('[CONSUMER] Consuming %s...' % n)
            time.sleep(1)
            r = '200 OK'
    
    def produce(c):
        c.next()
        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()
    
    if __name__=='__main__':
        c = consumer()
        produce(c)
    

    执行结果:

    [PRODUCER] Producing 1...
    [CONSUMER] Consuming 1...
    [PRODUCER] Consumer return: 200 OK
    [PRODUCER] Producing 2...
    [CONSUMER] Consuming 2...
    [PRODUCER] Consumer return: 200 OK
    [PRODUCER] Producing 3...
    [CONSUMER] Consuming 3...
    [PRODUCER] Consumer return: 200 OK
    [PRODUCER] Producing 4...
    [CONSUMER] Consuming 4...
    [PRODUCER] Consumer return: 200 OK
    [PRODUCER] Producing 5...
    [CONSUMER] Consuming 5...
    [PRODUCER] Consumer return: 200 OK
    

    注意到consumer函数是一个generator(生成器),把一个consumer传入produce后:
    1.首先调用c.next()启动生成器;
    2.然后,一旦生产了东西,通过c.send(n)切换到consumer执行;
    3.consumer通过yield拿到消息,处理,又通过yield把结果传回;
    4.produce拿到consumer处理的结果,继续生产下一条消息;
    5.produce决定不生产了,通过c.close()关闭consumer,整个过程结束。
    整个流程无锁,由一个线程执行,produce和consumer协作完成任务,所以称为“协程”,而非线程的抢占式多任务。

    参考:

    相关文章

      网友评论

          本文标题:知识点2-协程

          本文链接:https://www.haomeiwen.com/subject/jtlhjctx.html