4)协程一(yeild)
一:什么协程
协程: coroutine/coro
- 轻量级线程(一个线程)
- 调度由用户控制
- 有独立的寄存器上下文和栈
- 切换时保存状态,回来时恢复
二:协程和多线程比较
协程: coroutine/coro
- 轻量级线程(一个线程)
- 调度由用户控制
- 有独立的寄存器上下文和栈
- 切换时保存状态,回来时恢复
- 异步
- 一次调用,多个入口和结果
多进程,多线程
- 系统调度
- 上下文切换
- 占用内存
- 耗费CPU时间
- 同步
- 一次调用一次返回
三:python中协程发展
Python中协程的发展
•Python 2.5 (PEP 342) -> yield
•Python 3.3 (PEP 380) -> yield from
•Python 3.4 (PEP3156)-> asyncio
•Python 3.5 (PEP 0492).async/await
•Eventlet
•Greenlet
•gevent
四:协程使用发展
1.协程1期:模拟阶段
- 嵌套yield的函数交互运行
- next/send(None)激活yield
- send(data)向yield发送数据
示例1

1 import time 2 3 4 def consumer(): 5 r = '' 6 while True: 7 n = yield r #生成器,遇到yield就停止,并返回到porducer,等send信号,在继续向下执行,执行完了返回到yield处,并返回r 8 if not n: 9 return 10 print('[CONSUMR] Consuming %s' %n) 11 time.sleep(1) 12 r = '200 OK' 13 14 15 def produce(c): 16 next(c) #第一次调用生成器 17 n = 0 18 while n < 5: 19 n += 1 20 print('[PRODUCE] Producing %s' % n) 21 r = c.send(n) #给生成器发送数据,并把yeild返回的数据给r 22 print('[PRODUCE] Producing %s' % r,n) 23 c.close() 24 25 26 if __name__ == '__main__': 27 c = consumer() 28 produce(c)

# _*_ coding:utf-8 _*_ __author__ = "lixiang" from inspect import getgeneratorstate #协程使用生成器函数定义:定义体中有 yield 关键字 def simple_coro2(a): print("started:a=",a) b=yield a #遇到yield就停止,并把a返回给调用方 print("received:b=",b) c=yield a+b ##遇到yield就停止,并把a+b返回给调用方 print("received:c=",c) #协程中未处理的异常会向上冒泡,传给 next 函数或 send 方法的调用方 #如果没有return ,生成器会返回StopIteration异常 if __name__=="__main__": my_coro2=simple_coro2(14) #与创建生成器对象。 print(getgeneratorstate(my_coro2)) #inspect.getgeneratorstate生成器状态 r3=next(my_coro2) #next(my_coro2) 函数这一步通常称为“预激”(prime)协程==my_coro2.send(None) print(r3) #14 print(getgeneratorstate(my_coro2)) ##inspect.getgeneratorstate生成器状态 try: #仅当协程处于暂停状态时才能调用 send 方法,激活生成器,并绘生成器传值 r1=my_coro2.send(28) print(r1) #42 #生成器结束,传给 next 函数或 send 方法的调用方直接抛出异常 r2=my_coro2.send(99) #异常未执行 print(r2) #控制权流动到协程定义体的末尾,导致生成器像往常一样抛出 StopIteration异常 except StopIteration as e: print(e) 结果 ----------------- GEN_CREATED started:a= 14 14 GEN_SUSPENDED received:b= 28 42 received:c= 99

示例2:带return: # _*_ coding:utf-8 _*_ __author__ = "lixiang" from inspect import getgeneratorstate #协程使用生成器函数定义:定义体中有 yield 关键字 def simple_coro2(a): print("started:a=",a) b=yield a #遇到yield就停止,并把a返回给调用方 print("received:b=",b) c=yield a+b ##遇到yield就停止,并把a+b返回给调用方 print("received:c=",c) return c if __name__=="__main__": my_coro2=simple_coro2(14) #与创建生成器对象。 print(getgeneratorstate(my_coro2)) #inspect.getgeneratorstate生成器状态 r3=next(my_coro2) #next(my_coro2) 函数这一步通常称为“预激”(prime)协程==my_coro2.send(None) print(r3) #14 print(getgeneratorstate(my_coro2)) ##inspect.getgeneratorstate生成器状态 try: #仅当协程处于暂停状态时才能调用 send 方法,激活生成器,并绘生成器传值 r1=my_coro2.send(28) print(r1) #42 #生成器结束,直接抛出异常 my_coro2.send(99) #控制权流动到协程定义体的末尾,导致生成器像往常一样抛出 StopIteration异常 except StopIteration as e: print(e)#获取return返回值 结果:--------- GEN_CREATED started:a= 14 14 GEN_SUSPENDED received:b= 28 42 received:c= 99 99