async 和 await 是 Python 中用于实现协程并发编程的关键字。协程是一种特殊的函数,可以在执行过程中暂停,并在稍后恢复执行。这种特性使得协程非常适合处理 I/O 密集型任务,因为它们可以在等待 I/O 操作完成时让出控制权,从而允许其他任务运行。
- async:用于定义一个协程函数。当使用 async def 定义一个函数时,这个函数就变成了一个协程函数,调用它不会立即执行,而是返回一个协程对象。
- await:用于暂停当前协程的执行,等待另一个协程或异步操作完成。await 只能在 async 函数内部使用。
在 Python 中,协程的运行依赖于事件循环(event loop)。事件循环负责调度和执行协程。asyncio.run() 是 Python 3.7+ 推荐的方式,用于启动事件循环并运行一个协程。
- asyncio.run():用于启动事件循环并运行一个协程。它是 Python 3.7+ 推荐的方式,用于运行异步程序。
- asyncio.gather():用于并发运行多个协程。它会同时调度多个任务,而不是按顺序一个个执行。
在提供的案例中,ahello_world 是一个协程函数,它打印一条消息,然后使用 await asyncio.sleep(1) 暂停 1 秒,再打印另一条消息。amain 是另一个协程函数,它创建了两个 ahello_world 的任务,并分别使用 await 和 asyncio.gather() 来运行它们。
- 顺序执行:当使用 await task1 和 await task2 时,任务是按顺序执行的。这意味着 task1 必须完成,task2 才能开始。
- 并发执行:当使用 await asyncio.gather(ahello_world("Cat"), ahello_world("Dog")) 时,两个任务是并发执行的。这意味着它们可以同时运行,而不需要等待一个完成后再开始另一个。
输出结果展示了任务的执行顺序和时间。可以看到,当使用 await 顺序执行时,Bird 和 Rabbit 的任务是按顺序完成的。而当使用 asyncio.gather() 并发执行时,Cat 和 Dog 的任务几乎是同时开始的,因为它们是在等待 I/O 操作(asyncio.sleep)时让出控制权,允许其他任务运行。
总结:
- async 和 await 是 Python 中实现协程并发编程的关键字。
- 协程函数使用 async def 定义,调用时返回协程对象。
- await 用于暂停协程,等待异步操作完成。
- 事件循环负责调度和执行协程,asyncio.run() 是启动事件循环的推荐方式。
- asyncio.gather() 用于并发运行多个协程。
- 协程适合处理 I/O 密集型任务,可以在等待 I/O 操作时让出控制权,提高效率。