学习python异步编程asyncio之协程和任务

Awaitables

  • 定义: 如果一个对象可以在 await 表达式中被使用的话,那么这就是一个可等待的对象(awaitable object).
  • 三种可等待的对象: 协程coroutines, 任务Tasks 和 期望Futures.

协程 coroutines

  • 协程函数:一个由async def 定义的函数。
  • 协程对象: 通过调用协程函数所返回的对象。
  • python协程都是可等待的(awaitable),他们也能在其它协程中被等待。在某一个协程中, 如果不加 await关键字,只是普通调用另一个协程的话,不会执行任何东西。
  • 执行协程的三种方法:
    1. 使用await 关键字,如:await asyncio.sleep
    2. 使用asyncio.run()执行顶层入口函数。
    3. 使用asyncio.create_task() 将协程包装为任务,再用await 关键字。

任务Tasks

  • 用于并发编排协程。
  • 使用task = asyncio.create_task() 将一个协程包装成任务, 此函数返回Task。
  • task可以被取消, 也可以使用 await task 等待其完成。

期望Futures

  • 定义: 一种特殊的低层次可等待对象,用来表示一个异步操作的最终结果。
  • 一般来说无需在应用程序代码中显式创建Futures。

相关函数调用

  1. asyncio.run(coro, *, debug=False)
    • 此调用将执行传入的协程并返回结果,管理asyncio事件循环, 最终确定异步生成器, 并关闭线程池。
    • 当同一线程中已经有一个正在运行的asyncio事件循环,则此调用不可用。
    • debug 设为True, 则事件循环将在调试模式下运行。
    • 此调用会创建一个新的事件循环并在最后将其关闭。应该将其用作asyncio程序的主入口,且只调用一次。
  2. asyncio.create_task(coro, *, name=None)
  3. asyncio.sleep(delay, result=None)
    • 没啥可说的
  4. awaitable asyncio.gather(*aws, return_exceptions=False)
    • 以传入的aws中的顺序, 并发执行awaitable。
    • aws中的任何协程都会被自动安排为任务Task。
    • 默认抛出第一个异常, 但其它awaitable不会被取消而是继续执行。
  5. awaitable asyncio.shield(aw)
    • 使awaitable免于被取消
    • aw 若是协程,则被自动安排为任务Task。
    • res = await shield(something()) 等价于 res = await something(),唯一的区别是,如果包含这条语句的协程被取消,something()中跑着的Task不会被取消。对于something() 来说,取消从未发生过。
  6. coroutine asyncio.wait_for(aw, timeout)
    • 设置 awaitable的超时时限。
  7. asyncio.wait(aws, *, timeout=None, return_when=ALL_COMPLETED)
    • 并发执行aws中所有的awaitable, 在满足return_when指定的条件之前,将一直阻塞。
    • 返回值是 Futures 或 Tasks的集合:done, pending = await asyncio.wait(aws).
    • 如果设置timeout,则超时的Futures 或 Tasks 会被返回到pending 中
    • return_when 有三种可选值:FIRST_COMPLETED , FIRST_EXCEPTION , ALL_COMPLETED .
  8. asyncio.as_completed(aws, *, timeout=None)
    • 返回协程的迭代器

参考

https://docs.python.org/3/library/asyncio-task.html#coroutine

posted @ 2022-03-12 20:25  略略略——  阅读(432)  评论(0编辑  收藏  举报