【python 协程】10分钟了解下协程

协程

  • 协程,又称微线程,纤程。英文名Coroutine。
  • 子程序,或者称为函数,在所有语言中都是层级调用,比如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的执行有点像多线程,但协程的特点在于是一个线程执行,那和多线程比,协程有何优势?

最大的优势就是协程极高的执行效率。因为子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优势就越明显。

第二大优势就是不需要多线程的锁机制,因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断状态就好了,所以执行效率比多线程高很多。

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

Python对协程的支持是通过generator实现的。

在generator中,我们不但可以通过for循环来迭代,还可以不断调用next()函数获取由yield语句返回的下一个值。

但是Python的yield不但可以返回一个值,它还可以接收调用者发出的参数。
来看例子:

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

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

# encoding: utf-8
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
import time
time1=time.time()


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 < 100:
        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)
    time2=time.time()
    print u'ok,计算结束!'
    print u'总共耗时:'+str(time2-time1)+'s'

运行结果:

[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
[PRODUCER] Producing 6...
[CONSUMER] Consuming 6...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 7...
[CONSUMER] Consuming 7...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 8...
[CONSUMER] Consuming 8...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 9...
[CONSUMER] Consuming 9...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 10...
[CONSUMER] Consuming 10...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 11...
[CONSUMER] Consuming 11...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 12...
[CONSUMER] Consuming 12...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 13...
[CONSUMER] Consuming 13...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 14...
[CONSUMER] Consuming 14...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 15...
[CONSUMER] Consuming 15...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 16...
[CONSUMER] Consuming 16...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 17...
[CONSUMER] Consuming 17...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 18...
[CONSUMER] Consuming 18...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 19...
[CONSUMER] Consuming 19...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 20...
[CONSUMER] Consuming 20...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 21...
[CONSUMER] Consuming 21...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 22...
[CONSUMER] Consuming 22...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 23...
[CONSUMER] Consuming 23...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 24...
[CONSUMER] Consuming 24...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 25...
[CONSUMER] Consuming 25...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 26...
[CONSUMER] Consuming 26...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 27...
[CONSUMER] Consuming 27...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 28...
[CONSUMER] Consuming 28...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 29...
[CONSUMER] Consuming 29...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 30...
[CONSUMER] Consuming 30...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 31...
[CONSUMER] Consuming 31...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 32...
[CONSUMER] Consuming 32...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 33...
[CONSUMER] Consuming 33...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 34...
[CONSUMER] Consuming 34...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 35...
[CONSUMER] Consuming 35...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 36...
[CONSUMER] Consuming 36...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 37...
[CONSUMER] Consuming 37...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 38...
[CONSUMER] Consuming 38...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 39...
[CONSUMER] Consuming 39...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 40...
[CONSUMER] Consuming 40...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 41...
[CONSUMER] Consuming 41...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 42...
[CONSUMER] Consuming 42...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 43...
[CONSUMER] Consuming 43...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 44...
[CONSUMER] Consuming 44...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 45...
[CONSUMER] Consuming 45...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 46...
[CONSUMER] Consuming 46...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 47...
[CONSUMER] Consuming 47...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 48...
[CONSUMER] Consuming 48...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 49...
[CONSUMER] Consuming 49...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 50...
[CONSUMER] Consuming 50...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 51...
[CONSUMER] Consuming 51...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 52...
[CONSUMER] Consuming 52...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 53...
[CONSUMER] Consuming 53...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 54...
[CONSUMER] Consuming 54...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 55...
[CONSUMER] Consuming 55...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 56...
[CONSUMER] Consuming 56...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 57...
[CONSUMER] Consuming 57...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 58...
[CONSUMER] Consuming 58...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 59...
[CONSUMER] Consuming 59...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 60...
[CONSUMER] Consuming 60...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 61...
[CONSUMER] Consuming 61...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 62...
[CONSUMER] Consuming 62...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 63...
[CONSUMER] Consuming 63...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 64...
[CONSUMER] Consuming 64...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 65...
[CONSUMER] Consuming 65...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 66...
[CONSUMER] Consuming 66...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 67...
[CONSUMER] Consuming 67...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 68...
[CONSUMER] Consuming 68...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 69...
[CONSUMER] Consuming 69...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 70...
[CONSUMER] Consuming 70...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 71...
[CONSUMER] Consuming 71...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 72...
[CONSUMER] Consuming 72...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 73...
[CONSUMER] Consuming 73...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 74...
[CONSUMER] Consuming 74...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 75...
[CONSUMER] Consuming 75...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 76...
[CONSUMER] Consuming 76...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 77...
[CONSUMER] Consuming 77...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 78...
[CONSUMER] Consuming 78...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 79...
[CONSUMER] Consuming 79...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 80...
[CONSUMER] Consuming 80...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 81...
[CONSUMER] Consuming 81...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 82...
[CONSUMER] Consuming 82...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 83...
[CONSUMER] Consuming 83...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 84...
[CONSUMER] Consuming 84...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 85...
[CONSUMER] Consuming 85...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 86...
[CONSUMER] Consuming 86...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 87...
[CONSUMER] Consuming 87...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 88...
[CONSUMER] Consuming 88...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 89...
[CONSUMER] Consuming 89...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 90...
[CONSUMER] Consuming 90...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 91...
[CONSUMER] Consuming 91...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 92...
[CONSUMER] Consuming 92...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 93...
[CONSUMER] Consuming 93...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 94...
[CONSUMER] Consuming 94...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 95...
[CONSUMER] Consuming 95...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 96...
[CONSUMER] Consuming 96...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 97...
[CONSUMER] Consuming 97...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 98...
[CONSUMER] Consuming 98...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 99...
[CONSUMER] Consuming 99...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 100...
[CONSUMER] Consuming 100...
[PRODUCER] Consumer return: 200 OK
ok,计算结束!
总共耗时:0.0120000839233s

Process finished with exit code 0

参考源码:
https://github.com/michaelliao/learn-python3/blob/master/samples/async/coroutine.py

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页