Python基础入门 Day118 协程的概念与基本使用

147次阅读
没有评论

共计 1397 个字符,预计需要花费 4 分钟才能阅读完成。

协程(Coroutine)是一种比线程更轻量级的单元,它让我们能够以同步的写法实现异步的效果。与线程不同,协程本质上是用户态的“微线程”,由程序自行调度,而不是由操作系统进行调度,因此开销更低、性能更高。


一、为什么需要协程?

在处理 I/O 密集型任务时(例如网络请求、文件读写),程序会大量时间处于等待状态。
如果使用同步代码,等待会阻塞整个程序流程。

协程允许程序在遇到 I/O 阻塞时主动让出控制权,让其他任务运行,从而提高整体运行效率。


二、协程的基本语法:async 与 await

Python 从 3.5 开始引入原生协程语法:

import asyncio

async def hello():
    print("开始执行...")
    await asyncio.sleep(1)
    print("执行结束!")

asyncio.run(hello())

代码解析

  • async:定义一个协程函数
  • await:等待一个耗时操作,并让出控制权

三、多个协程并发执行

协程真正的力量来自于“并发”,例如同时执行多个任务:

import asyncio

async def task(name, sec):
    print(f"{name} 开始")
    await asyncio.sleep(sec)
    print(f"{name} 完成")

async def main():
    await asyncio.gather(task("任务 1", 1),
        task("任务 2", 2),
        task("任务 3", 1)
    )

asyncio.run(main())

效果

  • 三个任务会并发执行
  • 总耗时约 2 秒,而不是 1 + 2 + 1 = 4 秒

四、事件循环(Event Loop)

事件循环负责调度和运行协程,是协程背后的核心机制。

loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()

从 Python 3.7 开始,推荐使用更简单的:

asyncio.run(main())

五、协程的典型使用场景

1. 大量网络请求

如爬虫、接口聚合、批量 API 请求等。

2. Web 框架(如 FastAPI、aiohttp)

使用协程提升并发能力。

3. 高并发任务调度

协程让 Python 在 I/O 密集型任务中非常高效。


六、协程实战:并发爬取网页标题

import asyncio
import aiohttp

async def fetch_title(session, url):
    async with session.get(url) as resp:
        text = await resp.text()
        print(f"获取到内容:{url[:30]}...")

async def main():
    urls = [
        "https://www.python.org/",
        "https://www.google.com/",
        "https://www.github.com/"
    ]
    async with aiohttp.ClientSession() as session:
        tasks = [fetch_title(session, url) for url in urls]
        await asyncio.gather(*tasks)

asyncio.run(main())

七、小结

  • 协程是 I/O 密集型任务的利器,比线程更轻量
  • async/await 是核心语法
  • asyncio.gather 用于并发执行多个协程
  • 协程通过事件循环统一调度执行
  • 常用于爬虫、网络服务与高并发业务场景
正文完
 0
评论(没有评论)