协程 / Coroutine
目录
协程是在一个线程执行过程中可以在一个子程序的预定或者随机位置中断,然后转而执行别的子程序,在适当的时候再返回来接着执行。它本身是一种特殊的子程序或者称作函数。
一个程序可以包含多个协程,可以对比与一个进程包含多个线程。我们知道多个线程相对独立,有自己的上下文,切换受系统控制;而协程也相对独立,有自己的上下文,但是其切换由自己控制,由当前协程切换到其他协程由当前协程来控制。
下面以一个例子介绍一个简单的协程实现,
首先,模拟生产者和消费者模型,建立一个消费者函数,接收一个参数为传入的生产者,初始时使用next函数或send(None)来启动,然后连续7次调用send,将程序切入生产者answer,获取结果,最后调用close或send(None)来结束协程。
1 import time 2 3 4 def ask(a): 5 next(a) # Start generator 6 # a.send(None) 7 n = 0 8 while n < 7: # Ask certain number questions then exit. 9 print('Ask: Try to ask question %d' % n) 10 r = a.send(n) # Send Ques number (ask question), receive is r 11 print('Ask: Received answer <%s>' % r) 12 n += 1 13 a.close() # End loop 14 # try: 15 # a.send(None) 16 # except StopIteration as e: 17 # pass
接下来定义一个生产者answer,生产者会不停返回结果,除非收到None或被调用close函数从而结束。
1 def answer(): # Answer generator 2 ans = '' # First answer for generator start 3 while True: 4 qus = yield ans # Return answer 5 if qus is None: 6 return 7 print('Answer: Received question %s' % qus) 8 time.sleep(1) 9 ans = 'Best answer' 10 11 ask(answer())
运行得到结果,
Ask: Try to ask question 0 Answer: Received question 0 Ask: Received answer <Best answer> Ask: Try to ask question 1 Answer: Received question 1 Ask: Received answer <Best answer> Ask: Try to ask question 2 Answer: Received question 2 Ask: Received answer <Best answer> Ask: Try to ask question 3 Answer: Received question 3 Ask: Received answer <Best answer> Ask: Try to ask question 4 Answer: Received question 4 Ask: Received answer <Best answer> Ask: Try to ask question 5 Answer: Received question 5 Ask: Received answer <Best answer> Ask: Try to ask question 6 Answer: Received question 6 Ask: Received answer <Best answer>