深入理解asyncio

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

原文地址:https://www.cnblogs.com/xiondun/p/13665475.html