一、代码结构

import asyncio

async def compute(x, y):
    print('Compute %5 + %5' % (x, y))
    await asyncio.sleep(1)
    return x + y

async def print_sum(x, y):
    result = await compute(x, y)
    print('%s + %5 = %5' % (x, y, result))

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(print_sum(1, 2))
    loop.close()

二、关键知识点

1. 协程与子协程

  • async def 定义的函数是协程函数,调用时返回协程对象。
  • 在一个协程中 await 另一个协程,这个被 await 的协程就是子协程

2. 事件循环(Event Loop)

  • 事件循环是 asyncio 的核心,负责调度和执行所有协程任务。
  • 事件循环会自动管理协程的挂起、恢复、切换等。

3. await 的作用

  • await挂起当前协程,等待被 await 的协程或异步操作完成后再恢复执行。
  • 事件循环会在此期间调度其他任务。

三、逐行详细解释

1. 导入 asyncio

import asyncio
  • 导入 Python 的异步IO标准库。

2. 定义 compute 协程

async def compute(x, y):
    print('Compute %5 + %5' % (x, y))
    await asyncio.sleep(1)
    return x + y
  • async def compute(x, y):定义一个协程函数,参数为 x 和 y。
  • print('Compute %5 + %5' % (x, y)):格式化输出计算信息。
  • await asyncio.sleep(1)
    • 异步延时1秒,模拟耗时操作。
    • 这时 compute 协程会挂起,事件循环可以调度其他任务。
  • return x + y:1秒后返回 x + y 的结果。

3. 定义 print_sum 协程

async def print_sum(x, y):
    result = await compute(x, y)
    print('%s + %5 = %5' % (x, y, result))
  • async def print_sum(x, y):定义主协程。
  • result = await compute(x, y)
    • 挂起 print_sum 协程,调度 compute(x, y) 子协程。
    • 等 compute 执行完毕后,result 得到返回值。
  • print('%s + %5 = %5' % (x, y, result)):输出最终结果。

4. 主程序入口

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(print_sum(1, 2))
    loop.close()
  • loop = asyncio.get_event_loop():获取当前线程的事件循环对象。
  • loop.run_until_complete(print_sum(1, 2))
    • 启动事件循环,调度并执行 print_sum(1, 2) 协程,直到其执行完毕。
    • 事件循环会自动调度 print_sum 和 compute 两个协程的挂起与恢复。
  • loop.close():关闭事件循环,释放资源。

四、事件循环的调度机制

  1. 启动事件循环,调度 print_sum(1, 2) 协程。
  2. print_sum 执行到 await compute(1, 2),事件循环调度 compute(1, 2) 子协程。
  3. compute 执行到 await asyncio.sleep(1),协程挂起,事件循环等待1秒。
  4. 1秒后,compute 恢复,返回 3。
  5. print_sum 恢复,result 得到 3,输出 1 + 2 = 3
  6. print_sum 执行完毕,事件循环退出。

五、输出结果

Compute     1 +     2
1 +     2 =     3

(中间有1秒延迟)


六、核心原理总结

  • 事件循环自动调度所有协程和子协程的执行、挂起与恢复。
  • await 语句让协程可以暂停,等待异步操作或子协程完成后再继续。
  • 事件循环让你用同步风格写出高并发的异步代码,易读易维护。
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐