书中的代码用的应该是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