面试题答案
一键面试事件循环工作原理
- 概念:事件循环是异步编程的核心组件,它负责管理和调度程序中的异步任务。它不断地检查是否有新的任务需要执行,以及已执行的任务是否有结果返回。
- 运行机制:事件循环维护一个任务队列(task queue),其中存放着各种需要执行的协程任务。它从队列中取出任务,将其投入到执行器(如线程池或进程池)中执行,当任务执行完毕或等待I/O操作时,事件循环会暂停该任务,转而执行其他任务。当被暂停的任务所等待的事件(如I/O完成)发生时,该任务会被重新加入任务队列,等待事件循环再次调度执行。
在asyncio
库中事件循环对协程的管理和调度
- 创建事件循环:使用
asyncio.get_event_loop()
获取一个事件循环对象。在Python 3.7+ 可以使用asyncio.run()
,它内部创建并管理事件循环。 - 创建协程:使用
async def
定义一个协程函数,调用该函数返回一个协程对象。协程函数不会立即执行,而是返回一个可暂停和恢复的对象。 - 创建任务:将协程对象包装成任务对象(
Task
),任务对象是事件循环调度的基本单位。可以使用asyncio.create_task()
(Python 3.7+)或loop.create_task()
(旧版本)。 - 调度执行:事件循环按照一定的顺序从任务队列中取出任务执行,在执行过程中如果遇到
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())
在上述代码中:
task_function
是一个协程函数,它打印开始信息,然后使用await asyncio.sleep(2)
暂停2秒模拟I/O操作,最后打印结束信息。main
函数中,使用asyncio.create_task(task_function())
创建了一个任务,然后使用await task
等待任务完成。await
会暂停main
协程,直到task
执行完毕。asyncio.run(main())
创建并运行事件循环,事件循环会调度main
协程,进而调度task_function
任务。在task_function
等待asyncio.sleep(2)
时,事件循环会去检查是否有其他可执行的任务,由于没有其他任务,它会在2秒后继续执行task_function
剩下的部分。