import asyncio async def a(): print('Suspending a') await asyncio.sleep(0) print('Resuming a') async def b(): print('In b') async def main(): await asyncio.gather(a(), b()) if __name__ == '__main__': # asyncio.run(main()) loop = asyncio.get_event_loop() loop.run_until_complete(main()) loop.close()
import asyncio import time async def a(): print('Suspending a') await asyncio.sleep(3) print('Resuming a') async def b(): print('Suspending b') await asyncio.sleep(1) print('Resuming b') def show_perf(func): print('*' * 20) start = time.perf_counter() asyncio.run(func()) print(f'{func.__name__} Cost: {time.perf_counter() - start}') async def s1(): await a() await b() async def s2(): await asyncio.create_task(a()) await asyncio.create_task(b()) async def c1(): await asyncio.gather(a(), b()) async def c2(): await asyncio.wait([a(), b()]) async def c3(): task1 = asyncio.create_task(a()) task2 = asyncio.create_task(b()) await task1 await task2 async def c4(): task = asyncio.create_task(b()) await a() await task # asyncio.create_task是Python 3.7新增的高阶API,*是推荐的用法,其实你还可以用asyncio.ensure_future和loop.create_task: async def c5(): task = asyncio.ensure_future(b()) await a() await task async def c6(): loop = asyncio.get_event_loop() task = loop.create_task(b()) await a() await task # 到这里,我们一共看到2种错误的,6种正确的写法。你学到了么? if __name__ == '__main__': for f in (s1, s2, c1, c2, c3, c4, c5, c6): show_perf(f) # show_perf(s1) #s1 Cost: 4.0024491 # show_perf(s2) #s2 Cost: 4.0008178999999995 # show_perf(c1) #c1 Cost: 3.0059607 # show_perf(c2) #c2 Cost: 3.0032052 # show_perf(c3) #c3 Cost: 3.0028164 # show_perf(c4) #c4 Cost: 3.0043765000000002 # show_perf(c5) #c5 Cost: 3.0021667 # show_perf(c6) #c6 Cost: 3.0026876 print('完成')
import asyncio import time async def a(): print('Suspending a') await asyncio.sleep(3) print('Resuming a') return 'A' async def b(): print('Suspending b') await asyncio.sleep(1) print('Resuming b') return 'B' async def test(): # asyncio.gather封装的Task全程黑盒,只告诉你协程结果 # return_value_a, return_value_b = await asyncio.gather(a(), b()) # print(return_value_a, return_value_b) # asyncio.wait会返回封装的Task(包含已完成和挂起的任务),如果你关注协程执行结果你需要从对应Task实例里面用result方法自己拿 done, pending = await asyncio.wait([a(), b()]) print(done) print(pending) # list(done)[0].add_done_callback() list(done)[0].cancel() print(list(done)[0].result()) print(list(done)[1].result()) # asyncio.wait支持选择返回的时机,asyncio.wait支持一个接收参数return_when,在默认情况下,asyncio.wait会等待全部任务完成(return_when='ALL_COMPLETED'),它还支持FIRST_COMPLETED(第一个协程完成就返回)和FIRST_EXCEPTION(出现第一个异常就返回) done, pending = await asyncio.wait([a(), b()], return_when=asyncio.tasks.FIRST_COMPLETED) print('done:', done) print('pending:', pending) print(list(done)[0].result()) # 看到了吧,这次只有协程b完成了,协程a还是pending状态。 # 在大部分情况下,用asyncio.gather是足够的,如果你有特殊需求,可以选择asyncio.wait,举2个例子 # 1.需要拿到封装好的Task,以便取消或者添加成功回调等 # 2.业务上需要FIRST_COMPLETED/FIRST_EXCEPTION即返回的 def show_perf(func): print('*' * 20) start = time.perf_counter() asyncio.run(func()) print(f'{func.__name__} Cost: {time.perf_counter() - start}') if __name__ == '__main__': show_perf(test) # done, pending = await asyncio.wait([a(), b()]) print('完成')
https://zhuanlan.zhihu.com/p/73568282
https://zhuanlan.zhihu.com/p/75193842