Python 协程
外观
Python协程[编辑 | 编辑源代码]
协程(Coroutine)是Python中实现并发编程的一种轻量级方式,它允许函数在执行过程中暂停并在稍后恢复,而不阻塞整个线程。协程通过协作式多任务处理,使得多个任务可以在单个线程上高效切换,适用于I/O密集型操作。
简介[编辑 | 编辑源代码]
协程是一种特殊的生成器(Generator),它不仅可以生成值,还可以接收值。Python通过`async`和`await`关键字提供原生支持,使得协程的编写更加直观。协程的主要优势在于:
- 轻量级:比线程更节省资源。
- 非阻塞:适合处理高延迟的I/O操作(如网络请求、文件读写)。
- 高效:通过事件循环(Event Loop)管理任务调度。
基本语法[编辑 | 编辑源代码]
Python使用`async def`定义协程函数,并通过`await`调用其他协程或异步操作。
import asyncio
async def hello():
print("Hello")
await asyncio.sleep(1) # 模拟I/O操作
print("World")
# 运行协程
asyncio.run(hello())
输出:
Hello (等待1秒) World
协程与生成器的区别[编辑 | 编辑源代码]
协程是生成器的扩展,但两者关键区别在于:
- 生成器(Generator)通过`yield`产生值,但不能接收外部输入(除非使用`.send()`方法)。
- 协程(Coroutine)通过`await`挂起执行,并可以接收外部输入。
事件循环(Event Loop)[编辑 | 编辑源代码]
事件循环是协程调度的核心,负责管理多个协程的执行顺序。Python的`asyncio`模块提供了默认的事件循环实现。
实际案例:并发HTTP请求[编辑 | 编辑源代码]
以下示例展示如何使用协程并发发送多个HTTP请求:
import aiohttp
import asyncio
async def fetch_url(url):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return await response.text()
async def main():
urls = ["https://example.com", "https://example.org"]
tasks = [fetch_url(url) for url in urls]
results = await asyncio.gather(*tasks)
for result in results:
print(len(result)) # 打印网页内容长度
asyncio.run(main())
输出:
1270 # example.com的网页长度 1234 # example.org的网页长度
协程与多线程对比[编辑 | 编辑源代码]
特性 | 协程 | 多线程 |
---|---|---|
资源占用 | 低(单线程) | 高(每个线程占用独立内存) |
切换开销 | 极小(由事件循环管理) | 较大(依赖操作系统调度) |
适用场景 | I/O密集型任务 | CPU密集型任务 |
高级用法[编辑 | 编辑源代码]
协程嵌套[编辑 | 编辑源代码]
协程可以嵌套调用其他协程:
async def task1():
await asyncio.sleep(1)
return "Task 1 done"
async def task2():
await asyncio.sleep(2)
return "Task 2 done"
async def main():
result1 = await task1()
result2 = await task2()
print(result1, result2)
asyncio.run(main())
超时控制[编辑 | 编辑源代码]
使用`asyncio.wait_for`设置超时:
async def long_running_task():
await asyncio.sleep(10)
return "Done"
async def main():
try:
result = await asyncio.wait_for(long_running_task(), timeout=5)
except asyncio.TimeoutError:
print("Task timed out")
asyncio.run(main())
数学基础[编辑 | 编辑源代码]
协程的调度效率可以通过吞吐量(Throughput)衡量:
总结[编辑 | 编辑源代码]
- 协程是Python并发编程的核心工具之一,适合I/O密集型任务。
- 通过`async/await`语法实现,依赖事件循环调度。
- 比多线程更轻量级,但需要显式声明异步操作。