asyncio 是 Python 的一个内置库,它的主要用途是编写单线程并发代码,主要通过协程实现。这个库在 Python 3.4 版本中引入,作为 Python 的异步 I/O 框架,提供了基于事件循环的并发模型。

在 Python 3.4 之前,Python 的并发主要依赖于多线程和多进程,但这两种方式都有其局限性。多线程受到全局解释器锁(GIL)的限制,无法充分利用多核 CPU。而多进程虽然可以利用多核 CPU,但进程间的通信复杂,且开销大。因此,Python 社区开始寻找新的并发解决方案,最终在 Python 3.4 中引入了 asyncio

asyncio 的主要特点是事件循环和协程。事件循环是 asyncio 的核心,可以理解为一个无限循环,我们可以把一些函数(通过 async 定义的函数,称为协程)注册到事件循环上,当满足事件发生的条件时,调用相应的协程函数。

协程是 asyncio 的另一个重要概念。协程是一种比线程更轻量级的存在,协程的调度完全由用户控制,协程之间的切换不涉及系统调用,开销极小。Python 中的协程并不是线程安全的,它们应该运行在同一个线程中。如果想要在多线程中使用协程,需要为每个线程创建一个事件循环。

Python 3.5 版本对 asyncio 进行了进一步的改进,引入了新的关键字 asyncawait,使得协程的定义和调用更加简洁明了。

Python 3.7 版本对 asyncio 进行了一些优化和改进,增加了如 asyncio.run() 等新的 API,使得运行和管理协程更加方便。

协程异步函数

  1. 协程(Coroutines)和异步函数(Async Functions):

EventLoop

asyncio 模块在单线程上启动一个事件循环(event loop),时刻监听新进入循环的事件,加以处理,并不断重复这个过程,直到异步任务结束。事件循环的内部机制,可以参考 JavaScript 的模型,两者是一样的。

Untitled

gather 和 create_task

  1. 使用**asyncio.gather()**:
  2. 使用**asyncio.create_task()**:

case

import asyncio

async def task1():
    print("任务1开始")
    await asyncio.sleep(2)
    print("任务1完成")

async def task2():
    print("任务2开始")
    await asyncio.sleep(3)
    print("任务2完成")

async def main():
    print("程序开始")
    await asyncio.gather(task1(), task2())
    print("程序结束")

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

async def hello():
    print("Hello")
    await asyncio.sleep(1)  # 模拟耗时操作,挂起协程执行
    print("World")

async def main():
    await asyncio.gather(
        hello(),
        hello()
    )

asyncio.run(main())

参考