名词定义
任务:协程对象注册到事件循环后,y策略,执行函数中的操作; 任务的创建依赖已经启动的事件循环 loop.create_task(协程)
future:等价于任务,未完成的任务 ,通过asyncio.ensure_future(协程) 进行任务创建 Task是Future的子类
事件: event_loop, 启动事件循环,确保协程对象注册到事件循环,完成到任务的转化(任务状态:pending、running、done、cancel),await:等待任务结束
协程:Python的功能间切换着执行. 切换的点用 await 来标记使用async关键词将其变成协程方法,比如async def function():。其中,async 定义一个协程,await 用来挂起阻塞方法的执行
实践结论
先将task列表传入asyncio.gather()或 asyncio.wait()在传入run_until_complete中,比直接将task列表传入run_until_complete速度更快(即使task里面已经使用await进行等待任务):任务粒更细粒度化asyncio.gather(*tasks) 一定程度上等价于asyncio.wait(*tasks) , 但是:gather的入参为task,且*后携带的是可迭代的task列表;wait入参为future ;任务的工作流程:启动事件循环->协程方法注册到事件循环,封装成task->执行到await,释放cpu占用切给其他task,自己等待依赖的其他资源就绪->经过不固定CPU时间片,直到run_until_complete任务完成,拿到返回结果
典型的协程Demo
main方法中流程
loop = asyncio.get_event_loop()
tasks = [协程方法] # 将协程对象封装成任务对象
loop.run_until_complete(asyncio.gather(*tasks))
loop.close()
具体的代码示例如下:
回调函数:
协程定义函数funA
正常定义回调函数call_back_B
等任务A执行完,执行B
async def funA():
...
def call_back_B(task):
return task.result()
在main方法流程:
task = asyncio.ensure_future(协程)
task.add_done_callback(call_back_B)
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(task))
loop.close
多线程组合协程
主要用到concurrent.futrue.ThreadPoolExecuto线程池
创建Future对象:loop.run_in_executor(协程,pool)
async def funC():with concurrent.futures.ThreadPoolExecutor(max_workers = 10) as executor: loop = asyncio.get_event_loop() futures = ( loop.run_in_executor( executor, get_title, # 具体的操作 可以是协程也可以普通的函数 i) # i 为get_title的入参 for i in range(10) ) await asyncio.gather(*futures)
在main方法中流程:
loop = asyncio.get_event_loop()res = loop.run_until_complete(asyncio.gather(main()))