如何在Gevent中为特定线程内的代码块加锁,控制get请求执行顺序?
在Gevent中为协程代码块加锁实现串行执行
首先要明确一点:Gevent里提到的"线程"其实是Greenlet协程,不是操作系统级别的线程,所以不能直接用标准库的threading.Lock——Gevent的协程调度是在单线程内完成的,标准线程锁无法感知协程的切换,必须用Gevent自身提供的锁机制。
解决方案步骤:
- 导入Gevent专属的锁类:
from gevent.lock import Lock - 创建一个全局共享的锁实例(所有协程必须共用同一个锁才能实现同步)
- 用
with lock:上下文管理器包裹需要串行执行的完整代码块(包括start打印、get请求调用、end打印)
完整示例代码
import gevent from gevent.lock import Lock # 创建全局共享的锁对象 execution_lock = Lock() def process_request(thread_num): # 用with语句自动处理锁的获取与释放,避免手动操作出错 with execution_lock: print(f"Thread {thread_num} start") # 这里替换成你的实际get请求代码,比如 requests.get(...) # 模拟原代码中触发协程切换的IO操作 gevent.sleep(0.1) print(f"Thread {thread_num} end") # 启动两个协程任务 gevent.joinall([ gevent.spawn(process_request, 1), gevent.spawn(process_request, 2) ])
核心原理说明:
Lock是Gevent专为协程设计的同步原语,当一个协程持有锁时,其他协程会进入等待状态,直到锁被释放。with语句会自动在代码块开始时获取锁,结束时释放锁,即使代码块抛出异常也能保证锁正确释放。- 把整个需要原子执行的流程(从启动提示到结束提示)都放在锁保护范围内,就能保证一个协程完整执行完整个逻辑后,另一个协程才会开始执行。
运行这段代码后,输出就会变成:
Thread 1 start Thread 1 end Thread 2 start Thread 2 end
(如果你的原代码中Thread2仅输出"Thread 2",调整对应打印逻辑即可,核心锁机制完全通用)
内容的提问来源于stack exchange,提问作者Andriy
相关产品推荐
相关产品推荐

