Python协程

妖精的绣舞 提交于 2020-01-19 16:48:53

协程是一种实现并行编程的方法。不同于多线程或者多进程编程,各个协程其实还是在一个线程里运行,只是我们可以控制每个协程什么时候运行,什么时候停止,当一个协程停止时让另外的协程运行,从而达到并行计算的效果。运用协程的优点在于,因为所有的协程其实都是运行在一个线程里,因此它减少了在一个个协程间切换的代价,也不必考虑锁的问题。所以协程实现起来还是比较方便和简单的。
下面展示一个最简单的Python协程:

def coroutine():
    print "coroutine"
    x = 1
    n = yield x
    print n,x
    
c = coroutine()
x= c.next()
c.send(5)

输出如下:

coroutine
1
5 1
Traceback (most recent call last):
  File "C:\PythonScript\coroutine.py", line 11, in <module>
    c.send(5)
StopIteration

上面的代码中,首先生成协程对象c。之后需要执行一下c.next,程序会跑到coroutine函数中第一个yield的地方,并将yeild右边的值传给x。之后不断调用send,并将send中传入的参数赋值给n。当函数调用完毕的时候,会触发StopIteration的异常。

Python可以通过inspect.getgeneratorstate函数来获取协程的执行状态,该函数会返回下述字符串中的一个:
'GEN_CREATED':等待执行
'GEN_RUNNING':正在执行
'GEN_SUSPENED':在yield表达式处暂停
'GEN_CLOSE':执行结束

可以设置一个预激活协程的装饰器,通过该装饰器装饰协程后,就会预先启动next了。

from functools import wraps

def coroutine(func):
    @wraps(func)
    def primer(*args, **kwargs):
        gen = func(args, kwargs)
        next(gen)
        return gen
    return primer

最后展示一组运用协程实现的生产者消费者模型:

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()

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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!