MST

星途 面试题库

面试题:Python异步编程中的事件循环机制

描述Python异步编程中事件循环(event loop)的工作原理,以及在使用`asyncio`库进行异步编程时,事件循环是如何管理和调度协程的。请结合具体代码示例说明。
29.7万 热度难度
编程语言Python

知识考点

AI 面试

面试题答案

一键面试

事件循环工作原理

  1. 概念:事件循环是异步编程的核心组件,它负责管理和调度程序中的异步任务。它不断地检查是否有新的任务需要执行,以及已执行的任务是否有结果返回。
  2. 运行机制:事件循环维护一个任务队列(task queue),其中存放着各种需要执行的协程任务。它从队列中取出任务,将其投入到执行器(如线程池或进程池)中执行,当任务执行完毕或等待I/O操作时,事件循环会暂停该任务,转而执行其他任务。当被暂停的任务所等待的事件(如I/O完成)发生时,该任务会被重新加入任务队列,等待事件循环再次调度执行。

asyncio库中事件循环对协程的管理和调度

  1. 创建事件循环:使用asyncio.get_event_loop()获取一个事件循环对象。在Python 3.7+ 可以使用asyncio.run(),它内部创建并管理事件循环。
  2. 创建协程:使用async def定义一个协程函数,调用该函数返回一个协程对象。协程函数不会立即执行,而是返回一个可暂停和恢复的对象。
  3. 创建任务:将协程对象包装成任务对象(Task),任务对象是事件循环调度的基本单位。可以使用asyncio.create_task()(Python 3.7+)或loop.create_task()(旧版本)。
  4. 调度执行:事件循环按照一定的顺序从任务队列中取出任务执行,在执行过程中如果遇到await语句,事件循环会暂停当前任务,去执行其他任务,当await的对象完成后,再恢复当前任务。

代码示例

import asyncio


async def task_function():
    print('开始执行任务')
    await asyncio.sleep(2)
    print('任务执行完毕')


async def main():
    task = asyncio.create_task(task_function())
    print('任务已创建')
    await task
    print('所有任务执行完毕')


if __name__ == '__main__':
    asyncio.run(main())

在上述代码中:

  1. task_function是一个协程函数,它打印开始信息,然后使用await asyncio.sleep(2)暂停2秒模拟I/O操作,最后打印结束信息。
  2. main函数中,使用asyncio.create_task(task_function())创建了一个任务,然后使用await task等待任务完成。await会暂停main协程,直到task执行完毕。
  3. asyncio.run(main())创建并运行事件循环,事件循环会调度main协程,进而调度task_function任务。在task_function等待asyncio.sleep(2)时,事件循环会去检查是否有其他可执行的任务,由于没有其他任务,它会在2秒后继续执行task_function剩下的部分。