为何Python多线程测试代码中未出现Race Condition(竞态条件)?
为什么你的代码没出现竞态条件?
你的代码之所以没复现出竞态,核心原因是**self.initial_value += delta这个操作对应的字节码数量太少,在CPython的GIL(全局解释器锁)调度机制下,单个线程能一次性执行完所有相关字节码,不会被其他线程打断**。
具体细节:
- CPython的GIL默认会在一个线程执行约1000字节码后才释放,让其他线程抢占执行。
self.initial_value += delta拆解为字节码是:读取属性值、执行加法、写回属性,总共只有寥寥几条字节码,远低于GIL切换的阈值。所以每个线程的加法操作会完整执行,不会被中途打断,自然不会出现多个线程同时读取旧值、覆盖写入结果的竞态问题。- 你加的
sleep(1)是在加法之前,只是让所有线程几乎同时启动加法操作,但加法本身太快,GIL没来得及切换,所以最终结果依然正确。
如何复现竞态条件?
要触发竞态,需要在读取值和写回值之间插入一个会触发GIL释放的操作(比如短时间sleep、IO操作或耗时计算),让其他线程有机会在当前线程完成写回前读取到旧值。修改incerease方法如下:
def incerease(self, delta=1): current = self.initial_value sleep(0.001) # 释放GIL,让其他线程可抢占执行 self.initial_value = current + delta
运行修改后的代码,最终输出会小于250,就能看到明显的竞态效果了。
另外补充一个小优化:等待线程结束的代码可以简化为for t in threads: t.join(),比你写的while循环更简洁可靠。
内容的提问来源于stack exchange,提问作者Pexicade
相关产品推荐
相关产品推荐

