协程asyncio
通过 async /await 语法进行声明,是编写asyncio应用的推荐方式。
import asyncio
async def main():
print('hello')
await asyncio.sleep(1)
print('word')
asyncio.run(main())
结果:
hello
word //hello输出1秒后输出word
-
可等待对象 await
如果一个对象可以在await语句中使用,那么它就是可等待对象
例1:
import asyncio async def fun(): print("hhaha") re=await asyncio.sleep(2) #创建await等待对象 print('结束',re) asyncio.run(fun()) #调用协程
例2:
import asyncio async def others(): print('start') await asyncio.sleep(2) print('end') return '我是others' async def fun(): print("hhaha") #遇到IO操作挂起当前协程(任务),等IO操作完成之后再继续往下执行,当前协程挂起时,事件循环可以去执行其他协程(任务) re=await others() #创建await对象 print('结束',re) asyncio.run(fun()) #调用协程
结果:
hhaha start end 结束 我是others
实例3:
import asyncio async def others(): print('start') print('1') await asyncio.sleep(2) print('end') return '我是others' async def fun(): print("hhaha") re=await others() #创建await对象 print('结束', re) re1=await others() print('结束',re1) asyncio.run(fun()) #调用协程
结果:
hhaha start 1 end 结束 我是others start 1 end 结束 我是others
可等待对象有三种主要类型:协程,任务和Future
运行协程
import asyncio
import time
async def say_after(delay, what):
await asyncio.sleep(delay)
print(what)
async def main():
print(f"started at {time.strftime('%X')}")
await say_after(1, 'hello')
await say_after(2, 'world')
print(f"finished at {time.strftime('%X')}")
asyncio.run(main())
结果:
started at 23:48:48
hello
world
finished at 23:48:51
-
asyncio.create_task()函数用来并发运行作为asyncio任务的多个协程
import asyncio import time async def say_after(delay, what): await asyncio.sleep(delay) print(what) async def main(): #创建task对象,将say_after()函数加入事件循环 task1 = asyncio.create_task( say_after(1, 'hello')) #创建task对象,将say_after()函数加入事件循环 task2 = asyncio.create_task( say_after(2, 'world')) print(f"started at {time.strftime('%X')}") #当执行某协程遇到IO操作时,会自动切换到其他任务,此处的await是等待相应的协程全部执行完毕并获取结果 await task1 await task2 print(f"finished at {time.strftime('%X')}") asyncio.run(main())
结果:
started at 23:55:37 hello world finished at 23:55:39
比之前快了1秒
这里除了使用asyncio.create_task()函数以外,还可以用低层级的loop.create_task()或ensure_future()函数
注意:asyncio.create_task()实在3.7中被加入的
-
Future对象
task继承Future,task对象内部await结果的处理基于Future对象来的
import asyncio async def set_after(fut): await asyncio.sleep(2) fut.set_result('666') async def main(): #获取当前事件循环 loop=asyncio.get_running_loop() #创建一个任务(Future对象),没绑定任务行为,则这个任务永远不知道什么时候结束 fut=loop.create_future() #创建一个任务(task对象)绑定了set_after函数,函数内部再2秒之后, #会给fut赋值,即手动这是future任务的最终结果,那么fut就可以结束了 await loop.create_task(set_after(fut)) data=await fut print(data) asyncio.run(main())
结果:
666