Python协程

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

上面的代码中,首先生成协程对象c。之后需要执行一下c.next,程序会跑到coroutine函数中第一个yield的地方,并将yeild右边的值传给x。之后不断调用send,并将send中传入的参数赋值给n。当函数调用完毕的时候,会触发StopIteration的异常。
协程对象可以调用close函数,这样就不会触发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()
    print "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
原文地址:https://www.cnblogs.com/wickedpriest/p/12214340.html