Skip to content

实验 1:第一个 async 程序

这一节只做一件事:确认 async defawaitasyncio.run() 怎么配合。

运行:

bash
python3 examples/asyncio_demos/01_hello_async.py

代码:

python
import asyncio

async def main():
    print("Hello ...")
    await asyncio.sleep(1)
    print("... asyncio")

asyncio.run(main())

发生了什么

这里要记住一点:main() 在传给 asyncio.run() 前只是 coroutine object。创建 loop、调度 Task、运行到结束,这些事都是 asyncio.run() 做的。

运行时留意

  • Hello ... 立即输出。
  • 中间停 1 秒。
  • ... asyncio 输出后程序退出。

这 1 秒没有用 time.sleep() 堵住线程。当前 Task 在等一个定时器,事件循环这时可以去运行别的 Task。下一节会把多个等待放在一起跑,你会更明显地看到差别。

修改实验

await asyncio.sleep(1) 改成:

python
import time
time.sleep(1)

单个程序看起来输出差不多,但意义完全不同。time.sleep() 会堵住事件循环线程,后面实验里你会看到它对并发的破坏。

容易踩的坑

错误:

python
main()

这会创建 coroutine object,但不会执行。你通常会看到“coroutine was never awaited”的警告。

修正:

python
asyncio.run(main())

在 Jupyter、IPython 等已经运行事件循环的环境里,不能再嵌套 asyncio.run(),通常直接 await main()

面向学习目的的 Python asyncio 中文教程与 mini_asyncio 教学运行时。