Python中的协程状态管理与生命周期详解
字数 399 2025-11-17 10:28:11
Python中的协程状态管理与生命周期详解
协程的状态管理是理解异步编程的关键。协程在运行过程中会经历不同的状态,这些状态决定了协程当前能否被执行或是否已经完成。
1. 协程的三种基本状态
- GEN_CREATED:等待开始执行
- GEN_RUNNING:正在执行
- GEN_CLOSED:执行结束
2. 协程状态转换过程
import inspect
async def simple_coroutine():
print("协程开始")
await asyncio.sleep(0.1)
print("协程结束")
# 创建协程对象(GEN_CREATED状态)
coro = simple_coroutine()
print(f"初始状态: {inspect.getcoroutinestate(coro)}") # GEN_CREATED
# 运行协程(状态转换)
import asyncio
async def run_coroutine():
# 开始执行(GEN_RUNNING)
task = asyncio.create_task(coro)
await asyncio.sleep(0.05)
print(f"运行中状态: {inspect.getcoroutinestate(coro)}") # GEN_RUNNING
# 等待完成
await task
print(f"结束状态: {inspect.getcoroutinestate(coro)}") # GEN_CLOSED
asyncio.run(run_coroutine())
3. 协程生命周期的详细阶段
阶段1:创建(Creation)
async def lifecycle_example():
# 创建时协程处于挂起状态
print("第1步: 协程开始执行")
result = await asyncio.sleep(0.1, result="中间结果")
print("第2步: 收到await结果:", result)
return "最终结果"
# 创建但不执行
coro = lifecycle_example()
print(f"创建后状态: {inspect.getcoroutinestate(coro)}")
阶段2:启动(Starting)
async def start_coroutine():
coro = lifecycle_example()
# 第一次启动协程
try:
coro.send(None) # 启动协程执行
except StopIteration as e:
print("协程立即完成,返回值:", e.value)
except Exception as ex:
print("执行出错:", ex)
阶段3:挂起与恢复(Suspension & Resumption)
async def suspension_example():
print("A: 开始执行")
# 第一次挂起
value1 = await asyncio.sleep(0.1, result="第一次恢复")
print(f"B: 第一次恢复,收到值: {value1}")
# 第二次挂起
value2 = await asyncio.sleep(0.1, result="第二次恢复")
print(f"C: 第二次恢复,收到值: {value2}")
return "完成"
# 手动控制状态转换
async def manual_control():
coro = suspension_example()
try:
# 启动协程,执行到第一个await
result = coro.send(None)
print(f"第一次挂起,等待: {result}")
# 恢复执行,传递结果给第一个await
result = coro.send("手动传递的值")
print(f"第二次挂起,等待: {result}")
# 最终恢复
try:
coro.send("最终值")
except StopIteration as e:
print(f"协程完成,返回值: {e.value}")
except Exception as e:
print(f"执行出错: {e}")
4. 异常处理与状态管理
async def coroutine_with_errors():
try:
print("开始执行")
await asyncio.sleep(0.1)
raise ValueError("模拟错误")
except ValueError as e:
print(f"捕获错误: {e}")
await asyncio.sleep(0.1)
return "错误处理完成"
finally:
print("finally块执行")
async def error_handling_demo():
coro = coroutine_with_errors()
try:
# 正常执行
coro.send(None)
await asyncio.sleep(0.2)
# 检查状态
state = inspect.getcoroutinestate(coro)
print(f"错误处理后的状态: {state}")
except Exception as e:
print(f"外部捕获: {e}")
5. 协程的终止与清理
async def cleanup_coroutine():
try:
print("协程运行中")
await asyncio.sleep(1)
print("正常完成")
return "成功"
except asyncio.CancelledError:
print("协程被取消")
raise
finally:
print("清理资源")
async def cancellation_demo():
# 创建任务
task = asyncio.create_task(cleanup_coroutine())
# 等待一段时间后取消
await asyncio.sleep(0.1)
task.cancel()
try:
await task
except asyncio.CancelledError:
print("任务已取消")
# 检查最终状态
print(f"取消后状态: {inspect.getcoroutinestate(task.get_coro())}")
6. 协程状态监控实用工具
class CoroutineMonitor:
def __init__(self, coro):
self.coro = coro
self.states = []
async def run_with_monitoring(self):
self.states.append(inspect.getcoroutinestate(self.coro))
try:
while True:
try:
if inspect.getcoroutinestate(self.coro) == inspect.GEN_CREATED:
result = self.coro.send(None)
else:
result = self.coro.send("继续执行")
self.states.append(inspect.getcoroutinestate(self.coro))
await asyncio.sleep(0.1) # 模拟异步操作
except StopIteration as e:
self.states.append(inspect.getcoroutinestate(self.coro))
return e.value
except Exception as e:
self.states.append("ERROR: " + str(e))
raise
# 使用监控器
async def monitored_example():
await asyncio.sleep(0.1)
return "监控完成"
async def demo_monitor():
monitor = CoroutineMonitor(monitored_example())
result = await monitor.run_with_monitoring()
print(f"状态变化: {monitor.states}")
print(f"最终结果: {result}")
关键要点总结:
- 协程通过
send()方法推进执行,通过await表达式挂起 - 异常传播会改变协程状态,需要适当处理
- 协程终止时务必执行清理操作
- 状态监控有助于调试复杂的异步逻辑
- 理解状态转换是编写健壮异步代码的基础