书中的代码用的应该是Python3.3的,从Python3.5开始协程用async 与await 代替了@asyncio.coroutine与yield.from
话说asyncio与aiohttp配合使用,从书中的教程来看真的非常强大,以后的并发io处理,协程才是王道了。
18.1线程与协程对比
import threading import itertools import time import sys class Signal: go = True def spin(msg, signal): write, flush = sys.stdout.write, sys.stdout.flush for char in itertools.cycle(‘|/-\\‘): status = char + ‘ ‘ + msg write(status) flush() write(‘\x08‘ * len(status)) time.sleep(.1) if not signal.go: break write(‘ ‘ * len(status) + ‘\x08‘ * len(status)) def slow_function(): time.sleep(3) return 42 def supervisor(): singal = Signal() spinner = threading.Thread(target=spin, args=(‘thinking!‘, singal)) print(‘spinner object:‘, spinner) # spinner线程开始 spinner.start() # 主线程休眠 result = slow_function() # 给spinner线程发送关闭信号 singal.go = False spinner.join() return result def main(): result = supervisor() print(‘Answer‘, result) if __name__ == ‘__main__‘: main()
这个一个多线程的显示脚本,一共两个线程,主线程负责显示最后的输出,开辟的子线程负责显示转圈圈。
import asyncio import itertools import sys async def spin(msg): write, flush = sys.stdout.write, sys.stdout.flush for char in itertools.cycle(‘|/-\\‘): status = char + ‘ ‘ + msg write(status) flush() # 继续回到初始位置 write(‘\x08‘ * len(status)) try: await asyncio.sleep(.1) # 捕获错误 except asyncio.CancelledError: break write(‘ ‘ * len(status) + ‘\x08‘ * len(status)) async def slow_function(): await asyncio.sleep(3) return 42 async def supervisor(): # 把协程包装成为一个task任务 spinner = asyncio.ensure_future(spin(‘thinking!‘)) # 已经是一个任务返回的还是一个任务 spinner = asyncio.ensure_future(spinner) print(‘spinner object:‘, spinner) # 激活等待slow_function任务,由于slow_function里面有sleep,会把控制权,到时候会把控制权转给spinnner slow_function1 = asyncio.ensure_future(slow_function()) result = await slow_function1 # 得到result,取消spinner任务 # await asyncio.sleep(5) spinner.cancel() return result def main(): loop = asyncio.get_event_loop() result = loop.run_until_complete(supervisor()) loop.close() print(‘Answer‘, result) if __name__ == ‘__main__‘: main()
这是一个协程版本的,最后的协程supervisor()里面一共有两个任务,通过await asyncio.sleep()切换协程的工作。
asyncio.ensure_future(...)接收的是一个协程,排定它的运作时间,排定它的运行时间,然后返回个asyncio.Task实例,也就是asyncio.Future的实例,因为Task
是Future的子类,用于包装协程。
task或者future都有.done(), .add_done_callback(....)和.result()等方法,
只不过这些方法一般用的比较少,只要result=await myfuture(),其中await后面需要回调的参数就是,result就是task的result。
流畅的python,Fluent Python 第十八章笔记 (使用asyncio包处理并发)
原文:https://www.cnblogs.com/sidianok/p/12231548.html