找回密码
 立即注册
搜索
热搜: 活动 交友
查看: 506|回复: 0

Python 异步编程库 —— asyncio 简单入门

[复制链接]

14

主题

31

回帖

1060

积分

版主

积分
1060
发表于 10-7-2025 16:17:27 | 显示全部楼层 |阅读模式
本帖最后由 littleblackLB 于 10-7-2025 16:17 编辑

简单来说,异步是一种编程模型,区别于同步,允许程序在等待 I/O 操作时继续执行其他任务,从而提高了程序的并发性和效率。


何时使用异步?
对于 IO 密集型 (如文件读写、网络请求) 的任务,优先使用异步可以在提升效率基础下避免线程竞争,同时避免管理多线程的开销以减小 CPU 利用率。
对于 CPU 密集型任务,则使用多线程来并行处理任务,异步对于此类任务没有一点帮助。

定义
协程(Coroutine)
协程是 asyncio 的核心概念之一。它是一个特殊的函数,可以在执行过程中暂停,并在稍后恢复执行。
协程通过 async def 关键字定义,并通过 await 关键字暂停执行,等待异步操作完成。
  1. import asyncio

  2. async def say_hello():
  3.     print("Hello")
  4.     await asyncio.sleep(1)
  5.     print("World")
复制代码
当函数被 async 定义后,其不再是一个普通的函数,通过调用say_hello(),会返回一个 协程对象 (Coroutine Object)。因此要执行协程,需要将其作为任务或事件注册到事件循环中(如通过await)。

await 关键字
async 函数中,可以使用 await 关键字来等待一个异步操作完成。当遇到 await 时,协程函数会被暂停,等待异步操作完成后再继续执行。

事件循环
在 Python 中,asyncio 仅依赖单个线程,通过事件循环的机制来并发运行多个不同任务。
尽管具体的实现很复杂,但我们可以给出大概的原理:
  1. 协程列表 = [coro1, coro2, coro3, ...]

  2. while 协程列表不为空:
  3.     可执行的协程列表,已完成的协程列表 = 从协程列表中检查所有的协程并将'可执行'和'已完成'的协程返回
  4.    
  5.     for 就绪协程 in 可执行的协程列表:
  6.         尝试执行就绪协程
  7.         
  8.     for 已完成的协程 in 已完成的协程列表:
  9.         从协程列表中删除已完成的协程
复制代码
可执行的协程列表:这个列表包含了可以立即执行的协程,也就是那些没有阻塞等待外部资源(通常是 I/O 操作)的协程。这是事件循环的关键部分,因为异步编程的主要目的之一是在等待 I/O 操作时允许其他协程执行。

基本用法运行协程
要运行一个协程,你可以使用 asyncio.run() 函数。它会创建一个事件循环,并运行指定的协程。

  1. import asyncio

  2. async def main():
  3.     print("Start")
  4.     await asyncio.sleep(1)
  5.     print("End")

  6. asyncio.run(main())
复制代码

并发执行多个任务
使用 asyncio.gather() 函数并发执行多个协程,并等待它们全部完成。
  1. import asyncio

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

  6. async def task2():
  7.     print("Task 2 started")
  8.     await asyncio.sleep(2)
  9.     print("Task 2 finished")

  10. async def main():
  11.     await asyncio.gather(task1(), task2())

  12. asyncio.run(main())
复制代码
解释:
  • 假设 task1 会先被执行
  • 当执行到await asyncio.sleep(1)时,当前协程会中断,此时task2被执行
  • 当执行到await asyncio.sleep(1)时,由于所有协程都在等待,则主线程等待
  • 当task1的asyncio.sleep执行完后,重新获得执行权,执行完函数
  • task2同理
输出:
  1. Task 1 started
  2. Task 2 started
  3. Task 1 finished
  4. Task 2 finished
复制代码



您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|RealDevClub ( 沪ICP备2024093864号-1 )

GMT+8, 11-19-2025 03:14 , Processed in 0.094927 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表