标签:yield 问题 switch 多个 保存 执行 io操作 微软雅黑 next
协程,又称微线程,纤程。英文名coroutine。简单说:协程是一种用户态的轻量级线程。
协程拥有自己的寄存器上下文和栈。写成调度切换时,将寄存器上下文和栈保存到其他地方,在且回来的时候,恢复先前保存的寄存器上下文和栈。
因此,协程能保留上一次调用时的状态(即所有局部状态的一个特定组合),每次过程重入时,就相当于进入上一次调用的状态,换句话说:进入上一次离开时所处逻辑流的位置。
协程的优点:
缺点:
下面是一个使用yield实现协程的示例
import time, queue def consumer(name): #函数中使用yield语句,函数会变成一个生成器 print(‘Starting to sell iphone...‘) #2.1输出 3.1输出 while True: new_iphone = yield #2.2返回 3.2返回 print(‘%s bought a iphone %s‘ % (name, new_iphone)) #4.1 c1收到参数并输出 5.1 c2收到参数并输出 time.sleep(1) #4.2 c1睡1秒 5.2 c2睡1秒 def producer(): r = c1.__next__() #2 执行c1 r = c2.__next__() #3执行c2 n = 0 while n < 5: n += 1 c1.send(n) #4 c1传参n并返回至c1yield c2.send(n) #5 c2传参n并返回至c2yield print(‘[Producer] is producing iphone %s.‘ % n) #6输出 if __name__ == ‘__main__‘: #------>从这里开始 c1 = consumer(‘c1‘) #生成器c1 c2 = consumer(‘c2‘) #生成器c2 p = producer() #1 实例化并执行
结果
Starting to sell iphone... Starting to sell iphone... c1 bought a iphone 1 c2 bought a iphone 1 [Producer] is producing iphone 1. c1 bought a iphone 2 c2 bought a iphone 2 [Producer] is producing iphone 2. c1 bought a iphone 3 c2 bought a iphone 3 [Producer] is producing iphone 3. c1 bought a iphone 4 c2 bought a iphone 4 [Producer] is producing iphone 4. c1 bought a iphone 5 c2 bought a iphone 5 [Producer] is producing iphone 5.
以上就是使用yield实现一个协程的例子。
协程的标准定义:
基于以上4点,上面的示例严格说还不算真正的协程,因为它有一个功能没实现。
greenlet是一个用C实现的协程模块,相比与python自带的yield,它可以使你在任意函数之间随意切换,而不需把这个函数先声明为generator
from greenlet import greenlet #greenlet手动切换协程 def test1(): print(12) #2 gr2.switch() print(34) #4 gr2.switch() def test2(): print(56) #3 gr1.switch() print(78) #5 gr1 = greenlet(test1) #启动gr1协程 gr2 = greenlet(test2) #启动gr2协程 gr1.switch() #1
结果
12 56 34 78
感觉确实用着比generator还简单了呢,但好像还没有解决一个问题,就是遇到IO操作,自动切换,对不对?
标签:yield 问题 switch 多个 保存 执行 io操作 微软雅黑 next
原文地址:https://www.cnblogs.com/infinitecodes/p/12134008.html