返回到文章

采纳

编辑于 11天前

Python的asyncio介绍

python

asyncio 是 Python 用来编写 异步IO(Asynchronous I/O)程序的标准库,特别适合 处理高并发的 IO 密集型任务,比如网络请求、文件读取等。

与传统的多线程不同,asyncio 使用 协程(coroutines)事件循环(event loop) 来实现并发,能更高效地利用资源。

简单理解

  • async def 定义协程函数
  • await 等待耗时操作完成
  • asyncio.run() 启动事件循环并运行主协程

示例:模拟两个异步任务并发执行

import asyncio
import time

async def task(name, delay):
    print(f"{name} 开始")
    await asyncio.sleep(delay)  # 模拟异步耗时操作
    print(f"{name} 完成,耗时 {delay} 秒")

async def main():
    # 并发执行两个任务
    await asyncio.gather(
        task("任务1", 2),
        task("任务2", 3)
    )

start = time.time()
asyncio.run(main())
print(f"总耗时: {time.time() - start:.2f} 秒")

输出示例

任务1 开始
任务2 开始
任务1 完成,耗时 2 秒
任务2 完成,耗时 3 秒
总耗时: 3.00 秒

重点

  • 如果是同步写法,两个任务会顺序执行,总共需要 5 秒。
  • asyncio.gather() 并发执行多个协程,所以总耗时是最长的那个:3 秒。

下面是一个 手动管理事件循环asyncio 示例,展示了如何不用 asyncio.run(),而是通过手动创建、运行、关闭事件循环,并使用 asyncio.Event 来实现两个任务之间的通信。

示例:一个任务等待“事件”发生,另一个任务触发事件

import asyncio

async def waiter(event):
    print("waiter: 等待事件触发...")
    await event.wait()  # 阻塞直到事件被 set()
    print("waiter: 事件已触发,继续执行")

async def setter(event):
    print("setter: 3 秒后触发事件")
    await asyncio.sleep(3)
    event.set()
    print("setter: 事件已触发")

# 手动管理事件循环
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)

event = asyncio.Event()

try:
    # 手动运行事件循环,直到两个任务都完成
    loop.run_until_complete(
        asyncio.gather(waiter(event), setter(event))
    )
finally:
    loop.close()

输出示例

waiter: 等待事件触发...
setter: 3 秒后触发事件
setter: 事件已触发
waiter: 事件已触发,继续执行

解释

  • asyncio.Event() 是一个简单的线程/协程同步工具。
  • event.wait() 让协程挂起,直到事件状态变为“已设置”。
  • event.set() 改变事件状态,所有等待它的协程会继续执行。
  • loop.run_until_complete() 是手动控制事件循环的关键。