
在 Python 中,greenlet 是一个轻量级的协程库,允许你在同一个线程内手动控制多个执行流的切换。要实现两个或多个 greenlet 交替运行,关键在于通过 switch() 和 parent 的方式显式地在它们之间跳转。
基本原理:greenlet 的切换机制
每个 greenlet 都是一个独立的执行上下文。通过调用 gr.switch() 方法,可以把控制权转移到指定的 greenlet。初始 greenlet(main greenlet)通常作为“父”greenlet存在。
注意: 第一次必须由 parent 启动子 greenlet,之后它们才能互相切换。
示例:两个 greenlet 交替打印数字
下面是一个简单的例子,展示两个 greenlet 如何交替运行:
立即学习“Python免费学习笔记(深入)”;
from greenlet import greenlet
<p>def task1():
for i in range(5):
print(f"Task1: {i}")
gr2.switch() # 切换到 task2</p><p>def task2():
for i in range(5):
print(f"Task2: {i}")
gr1.switch() # 切换回 task1</p><h1>创建 greenlet 对象</h1><p>gr1 = greenlet(task1)
gr2 = greenlet(task2)</p><h1>启动第一个任务(从 main greenlet 切入 gr1)</h1><p>gr1.switch()
输出结果为:
Task1: 0 Task2: 1 Task1: 1 Task2: 2 Task1: 2 ...
可以看到,控制权在 gr1 和 gr2 之间来回切换。
如何实现更灵活的交替控制
你也可以让某个 greenlet 执行完再切回来,或者传值交换:
from greenlet import greenlet
<p>def producer():
for i in range(3):
print(f"Producing {i}")
value = gr_consumer.switch(i) # 发送数据并切换
print(f"Received ack: {value}")</p><p>def consumer():
while True:
value = gr_producer.switch() # 等待接收
print(f"Consumed: {value}")
gr_producer.switch("done")</p><p>gr_producer = greenlet(producer)
gr_consumer = greenlet(consumer)</p><p>gr_producer.switch()
这个例子展示了 greenlet 之间的双向通信和协作式调度。
注意事项与使用场景
- greenlet 不是线程安全的,不能并发执行,只是协同式多任务。
- 适合用于实现状态机、协程框架(如 gevent 底层就基于 greenlet)。
- 手动管理切换逻辑较繁琐,复杂流程建议使用 asyncio + async/await。
基本上就这些。greenlet 的交替运行依赖于你主动调用 switch() 去触发上下文切换,没有自动调度器,所以控制清晰但需要自己设计流转逻辑。











