Python多线程场景下执行list(d.items())操作是否线程安全?
核心问题:多线程场景下执行
list(d.items())是否安全 以下是待验证的多线程测试代码:
import threading n = 2000 d = {} def dict_to_list(): while True: list(d.items()) # 此处操作是否安全? def modify(): for i in range(n): d[i] = i if __name__ == "__main__": t1 = threading.Thread(target=dict_to_list, daemon=True) t1.start() t2 = threading.Thread(target=modify, daemon=True) t2.start() t2.join()
相关机制说明
字典的item视图对应迭代器,会在每一步迭代执行时校验字典大小是否发生变更,可通过如下代码验证该行为:
d = {} view = d.items() # 这是一个可迭代对象 it = iter(view) # 这是一个正式的迭代器 d[1] = 1 print(list(view)) # 操作正常,输出结果为[(1, 1)] print(list(it)) # 抛出RuntimeError,原因是迭代过程中字典大小发生了变更
理论推导与实际现象
基于上述机制可推导:如果上述多线程示例中的list(...)调用过程可被线程调度中断(即执行该操作的t1线程在过程中释放GIL),程序应当会在t1线程中触发RuntimeError。
已知公开资料指出这类列表转换操作不具备原子性,但实际反复运行上述多线程示例,始终无法复现预期的崩溃问题。
明确知晓使用互斥锁是这类共享资源操作下更稳妥的实现方案,无需依赖特定操作的原子性特性,但当前正在调试某第三方库的同类代码问题,且无法直接修改该库的实现逻辑。
内容的提问来源于stack exchange,提问作者user14278279
相关产品推荐
相关产品推荐

