知行编程网知行编程网  2022-12-13 17:00 知行编程网 隐藏边栏  1 
文章评分 0 次,平均分 0.0
导语: 本文主要介绍了关于一篇文章带你读懂Python的协程的相关知识,包括我读懂了什么,以及作文《读懂》这些编程知识,希望对大家有参考作用。

一篇文章带你了解Python的协程

协程,又称微线程,纤程。英文名Coroutine。

协程的概念由来已久,只是近几年才在一些语言如Lua中得到广泛应用。

子例程或函数在所有语言中都是按层次结构调用的。比如A调用B,B在执行过程中调用C,C执行完返回,B执行完返回,最后A执行完毕。

所以子程序调用是通过栈实现的,一个线程执行一个子程序。

子程序调用总是一进一出,调用顺序明确。协程的调用不同于子例程。

协程看起来也像一个子程序,但是在执行过程中,可以在子程序内部中断,然后转而去执行其他的子程序,在合适的时候再返回继续执行。

注意在一个子程序中打断去执行其他子程序不是函数调用,有点类似于CPU中断。例如,子程序 A 和 B:

def A():
    print '1'
    print '2'
    print '3'
def B():
    print 'x'
    print 'y'
    print 'z'

假设它是由协程执行的,在执行A的过程中,可以随时中断执行B,执行过程中也可能中断B,然后执行A。结果可能是:

1
2
x
y
3
z

但是在A中,并没有调用B,所以协程的调用比函数调用更难理解。

看起来A和B的执行有点像多线程,但是coroutine的特点是一个线程执行。与多线程相比,协程有什么优势?

优点是协程的执行效率极高。因为子程序切换不是线程切换,而是由程序自己控制的,所以没有线程切换的开销。与多线程相比,线程越多,协程的性能优势越明显。

第二大优点是不需要多线程的锁机制,因为只有一个线程,同时写变量不存在冲突。在协程中,对共享资源进行无锁控制,只需要判断状态即可,因此执行效率比很多线程高很多。

因为协程是一个线程执行的,如何使用多核CPU呢?最简单的方法就是多进程+协程,既充分利用了多核,又充分发挥了协程的高效性,可以获得极高的性能。

Python对协程的支持还是很有限的,生成器中使用的yield可以在一定程度上实现协程。虽然支撑还不完整,但已经可以发挥出不小的威力了。

来看例子:

传统的生产者消费者模型是一个线程写消息,一个线程取消息,通过锁机制控制队列和等待,但一不小心就可能死锁。

如果换成协程,producer生产消息后,直接通过yield跳转到consumer开始执行。消费者执行完后,切换回生产者继续生产,效率极高:

import timedef 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)

执行结果:

一篇文章带你了解Python的协程

注意到consumer函数是一个generator(生成器),把一个consumer传入produce后:

首先调用c.next()启动生成器;

然后,一旦生产了东西,通过c.send(n)切换到consumer执行;

consumer通过yield拿到消息,处理,又通过yield把结果传回;

produce拿到consumer处理的结果,继续生产下一条消息;

produce决定不生产了,通过c.close()关闭consumer,整个过程结束。

整个过程是无锁的,一个线程执行。生产者和消费者协作完成任务,所以称为“协程”而不是线程抢占式多任务。

最后套用Donald Knuth的一句话总结协程的特点:

“子程序就是协程的一种特例。”

本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

知行编程网
知行编程网 关注:1    粉丝:1
这个人很懒,什么都没写
扫一扫二维码分享