运行器

源代码: Lib/asyncio/runners.py

此节提纲了运行 asyncio 代码的高级 asyncio 原语。

它们的构建是基于 事件循环 旨在简化常见广泛零散情景下的 async 代码使用。

运行异步程序

asyncio. run ( coro , * , debug = None )

执行 协程 coro 并返回结果。

此函数运行传递的协程,负责管理 asyncio 事件循环, 定稿异步生成器 及关闭线程池。

无法调用此函数,当另一 asyncio 事件循环在同一线程中运行时。

debug is True ,以调试模式运行事件循环。 False 明确禁用调试模式。 None 用于遵守全局 调试模式 设置。

此函数总是创建新事件循环,并在结束时关闭它。它应被用作 asyncio 程序的主入口点,且理想情况下只应被调用一次。

范例:

async def main():
    await asyncio.sleep(1)
    print('hello')
asyncio.run(main())
						

3.7 版新增。

3.9 版改变: 更新为使用 loop.shutdown_default_executor() .

3.10 版改变: debug is None 默认情况下,将遵守全局调试模式设置。

Runner 上下文管理器

class asyncio. Runner ( * , debug = None , loop_factory = None )

上下文管理器能简化 multiple async 函数调用在同一上下文中。

有时,应该调用几个顶层 async 函数在同一 事件循环 and contextvars.Context .

debug is True ,以调试模式运行事件循环。 False 明确禁用调试模式。 None 用于遵守全局 调试模式 设置。

loop_factory 可以用于覆盖循环创建。它负责 loop_factory 将创建的循环设为当前循环。默认情况下 asyncio.new_event_loop() 被使用并设为当前事件循环采用 asyncio.set_event_loop() if loop_factory is None .

基本上, asyncio.run() 范例可以按 Runner 用法重写:

async def main():
    await asyncio.sleep(1)
    print('hello')
with asyncio.Runner() as runner:
    runner.run(main())
					

3.11 版新增。

run ( coro , * , context = None )

运行 协程 coro 在嵌入循环中。

返回协程结果 (或引发其异常)。

可选仅关键词 context 自变量允许指定自定义 contextvars.Context coro 以在其中运行。使用 Runner 的默认上下文若为 None .

无法调用此函数,当另一 asyncio 事件循环在同一线程中运行时。

close ( )

关闭 Runner。

定稿异步生成器,关闭默认执行器,关闭事件循环及释放嵌入 contextvars.Context .

get_loop ( )

返回 Runner 实例关联的事件循环。

注意

Runner 使用惰性初始化战略,其构造函数不会初始化底层低级结构。

嵌入 loop and context 的创建是在 with 本体进入或首次调用 run() or get_loop() .

处理键盘中断

3.11 版新增。

signal.SIGINT 被引发通过 Ctrl - C , KeyboardInterrupt exception is raised in the main thread by default. However this doesn’t work with asyncio because it can interrupt asyncio internals and can hang the program from exiting.

To mitigate this issue, asyncio 处理 signal.SIGINT 如下:

  1. asyncio.Runner.run() installs a custom signal.SIGINT handler before any user code is executed and removes it when exiting from the function.

  2. Runner creates the main task for the passed coroutine for its execution.

  3. signal.SIGINT 被引发通过 Ctrl - C , the custom signal handler cancels the main task by calling asyncio.Task.cancel() which raises asyncio.CancelledError inside the main task. This causes the Python stack to unwind, try/except and try/finally blocks can be used for resource cleanup. After the main task is cancelled, asyncio.Runner.run() 引发 KeyboardInterrupt .

  4. A user could write a tight loop which cannot be interrupted by asyncio.Task.cancel() , in which case the second following Ctrl - C immediately raises the KeyboardInterrupt without cancelling the main task.

内容表

上一话题

asyncio — 异步 I/O

下一话题

协程和任务

本页