线程通知实现对比:单次触发场景下Boolean能否替代threading.Event
单次触发场景下用Boolean变量替代
threading.Event的线程安全性求证 我认为即便是移除GIL的场景下,使用Boolean变量替代单次触发的threading.Event变量也是线程安全的,特此求证。
示例替换方案
前者为threading.Event实现,后者为Boolean变量实现:
class Test(threading.Thread): def __init__(self): self.stop_var = threading.Event() def run(self): while not self.stop_var.is_set(): do_work() def stop(self): self.stop_var.set()
class Test(threading.Thread): def __init__(self): self.stop_var = False def run(self): while not self.stop_var: do_work() def stop(self): self.stop_var = True
核心逻辑说明
由于stop_var仅会在跨线程场景下被设置一次,赋值后会永久保持为True,不存在数据竞争(data race)。严格来说设置和读取stop_var的操作之间存在竞态条件(race condition),但无论哪一操作先执行,最终线程都会停止的结果是恒定的,差异仅在于循环是否多执行一次,程序最终必定会停止。另外需要指出,Event内部使用的锁也存在同样的竞态条件,因为锁本身无法保证操作顺序。
如果是需要反复切换Boolean变量值的场景,这种替换就会出现问题,此时应该使用锁来避免数据竞争,必要时搭配notify/wait机制避免竞态条件,换言之这种场景应当使用
Event。
现有讨论问题说明
这个问题经常被提及但始终没有得到明确解答:比如已有相关回答被GIL相关内容带偏,没有正面回应问题;而另一则回答的内容是完全错误的,正如其下评论“是否该重新审视这个回答了?”所说,我认为确实到了需要重新澄清的时刻。
参考概念说明
- 并发编程场景下“data race”和“race condition”是否实际为同一概念
- 竞态条件与数据竞争的定义差异
内容的提问来源于stack exchange,提问作者user19087
相关产品推荐
相关产品推荐

