Python3 `asyncio` — 异步 I/O,事件循环和并发工具

Python3 asyncio — 异步 I/O,事件循环和并发工具

在 Python 编程中,asyncio 是用于编写并发代码的标准库。它使得 Python 程序能够高效地处理 I/O 密集型任务,如网络请求、文件读取等,特别是在需要同时处理大量并发任务时。asyncio 的核心思想是异步 I/O,基于事件循环机制,让多个任务在同一个线程中并发执行,而不需要多线程或多进程的复杂处理。

本文将详细介绍 Python3 中的 asyncio 模块,包括如何使用事件循环、异步 I/O 任务和并发工具,以及通过代码示例帮助你掌握其核心概念和应用场景。


一、什么是 asyncio

asyncio 是 Python 3.3 引入的标准库,用于支持异步编程。它提供了一个事件循环机制,可以在同一个线程中调度和执行多个 I/O 密集型任务。asyncio 使得 Python 能够以非阻塞的方式运行多个任务,从而提高了处理并发任务的效率。

1.1 主要概念

  • 事件循环(Event Loop):是 asyncio 的核心,负责调度任务和执行异步操作。它会不断地检查哪些任务已经完成,哪些任务需要等待,并在适当的时机运行它们。
  • 协程(Coroutines):是 Python 中定义的异步函数,它通过 async 关键字声明,await 关键字用于暂停协程的执行,等待某个异步操作完成。
  • 任务(Tasks):协程的封装,可以将多个协程调度并行执行。
  • Future:表示将来某个时刻完成的异步操作的结果。Future 是一个特殊的对象,它用来表示一个尚未完成的操作的结果。

二、事件循环(Event Loop)

事件循环是 asyncio 的基础,控制着异步操作的执行流程。在 asyncio 中,程序通过事件循环来执行多个协程。通常情况下,你不需要手动创建事件循环,asyncio.run() 函数会自动为你创建并运行事件循环。

2.1 使用 asyncio.run() 启动事件循环

import asyncio

async def say_hello():
    print("Hello, world!")

# 启动事件循环
asyncio.run(say_hello())

解释

  • 使用 async def 定义一个异步协程 say_hello()
  • asyncio.run() 启动事件循环,执行 say_hello() 协程。

2.2 事件循环中的异步任务

在事件循环中,多个异步任务可以并发执行。asyncio.create_task() 用于将协程包装成任务,并将其调度到事件循环中执行。

import asyncio

async def task1():
    print("Task 1 started")
    await asyncio.sleep(2)
    print("Task 1 finished")

async def task2():
    print("Task 2 started")
    await asyncio.sleep(1)
    print("Task 2 finished")

async def main():
    # 创建并启动任务
    task1_obj = asyncio.create_task(task1())
    task2_obj = asyncio.create_task(task2())
    
    # 等待任务完成
    await task1_obj
    await task2_obj

# 启动事件循环
asyncio.run(main())

解释

  • asyncio.create_task()task1()task2() 协程创建为任务,并交给事件循环。
  • await 等待任务完成,确保事件循环在所有任务完成后才结束。

输出

Task 1 started
Task 2 started
Task 2 finished
Task 1 finished

从输出可以看出,两个任务并发执行,task2() 完成后 task1() 继续执行。


三、异步 I/O 操作

异步 I/O 操作允许我们在等待 I/O 操作完成时不阻塞整个程序。asyncio 提供了异步版本的 I/O 操作,例如 asyncio.sleep()asyncio.gather() 等。

3.1 asyncio.sleep():模拟 I/O 操作

asyncio.sleep() 是一个模拟延时的异步操作。它不会阻塞事件循环,在等待过程中可以执行其他任务。

import asyncio

async def async_task(name, seconds):
    print(f"Task {name} started")
    await asyncio.sleep(seconds)
    print(f"Task {name} finished after {seconds} seconds")

async def main():
    # 启动多个异步任务
    await asyncio.gather(
        async_task("A", 2),
        async_task("B", 1),
        async_task("C", 3)
    )

# 启动事件循环
asyncio.run(main())

解释

  • asyncio.gather() 用来并发执行多个异步任务,并等待所有任务完成。
  • asyncio.sleep() 使当前协程暂停一段时间,模拟 I/O 操作。

输出

Task A started
Task B started
Task C started
Task B finished after 1 seconds
Task A finished after 2 seconds
Task C finished after 3 seconds

四、并发工具:asyncio.gather()await

4.1 asyncio.gather():并发执行多个协程

asyncio.gather() 可以并发执行多个协程,并等待它们的结果。它非常适用于需要并行执行多个任务的场景。

import asyncio

async def fetch_data(url):
    print(f"Fetching data from {url}")
    await asyncio.sleep(2)  # 模拟 I/O 操作
    return f"Data from {url}"

async def main():
    urls = ["https://example.com", "https://google.com", "https://github.com"]
    # 同时请求多个网址
    results = await asyncio.gather(*(fetch_data(url) for url in urls))
    print(results)

# 启动事件循环
asyncio.run(main())

解释

  • asyncio.gather() 用于并行执行多个协程,返回它们的结果。
  • *(fetch_data(url) for url in urls) 使用生成器表达式创建多个协程。

输出

Fetching data from https://example.com
Fetching data from https://google.com
Fetching data from https://github.com
Data from https://example.com
Data from https://google.com
Data from https://github.com

4.2 任务的结果处理

asyncio.gather() 会返回所有任务的结果,可以直接对结果进行处理。

import asyncio

async def task(name, seconds):
    await asyncio.sleep(seconds)
    return f"Task {name} finished after {seconds} seconds"

async def main():
    tasks = [
        asyncio.create_task(task("A", 1)),
        asyncio.create_task(task("B", 2)),
        asyncio.create_task(task("C", 3))
    ]
    
    # 获取任务结果
    results = await asyncio.gather(*tasks)
    print(results)

# 启动事件循环
asyncio.run(main())

解释

  • asyncio.create_task() 创建任务并并发执行。
  • asyncio.gather() 返回任务的执行结果。

输出

['Task A finished after 1 seconds', 'Task B finished after 2 seconds', 'Task C finished after 3 seconds']

五、总结

asyncio 是 Python3 提供的一个强大工具,用于简化异步 I/O 操作和并发编程。通过事件循环和协程,asyncio 能够高效地执行多个任务而不阻塞程序的执行。主要功能包括:

  • 异步 I/O 操作,避免阻塞。
  • 使用 asyncawait 定义协程。
  • 使用 asyncio.create_task() 调度任务。
  • 使用 asyncio.gather() 并发执行多个协程。

理解并掌握 asyncio 的基本概念和用法,可以帮助你高效地处理 I/O 密集型任务,提升程序的并发能力。

希望这篇教程能帮助你更好地理解 Python 中的异步编程,并应用到实际项目中!

最后修改于:2024年11月30日 21:40

评论已关闭

推荐阅读

DDPG 模型解析,附Pytorch完整代码
2024年11月24日
DQN 模型解析,附Pytorch完整代码
2024年11月24日
AIGC实战——Transformer模型
2024年12月01日
Socket TCP 和 UDP 编程基础(Python)
2024年11月30日
python , tcp , udp
如何使用 ChatGPT 进行学术润色?你需要这些指令
2024年12月01日
AI
最新 Python 调用 OpenAi 详细教程实现问答、图像合成、图像理解、语音合成、语音识别(详细教程)
2024年11月24日
ChatGPT 和 DALL·E 2 配合生成故事绘本
2024年12月01日
omegaconf,一个超强的 Python 库!
2024年11月24日
【视觉AIGC识别】误差特征、人脸伪造检测、其他类型假图检测
2024年12月01日
[超级详细]如何在深度学习训练模型过程中使用 GPU 加速
2024年11月29日
Python 物理引擎pymunk最完整教程
2024年11月27日
MediaPipe 人体姿态与手指关键点检测教程
2024年11月27日
深入了解 Taipy:Python 打造 Web 应用的全面教程
2024年11月26日
基于Transformer的时间序列预测模型
2024年11月25日
Python在金融大数据分析中的AI应用(股价分析、量化交易)实战
2024年11月25日
AIGC Gradio系列学习教程之Components
2024年12月01日
Python3 `asyncio` — 异步 I/O,事件循环和并发工具
2024年11月30日
llama-factory SFT系列教程:大模型在自定义数据集 LoRA 训练与部署
2024年12月01日
Python 多线程和多进程用法
2024年11月24日
Python socket详解,全网最全教程
2024年11月27日