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