Python多线程场景下字典新旧数据始终一致问题排查
问题原因及修复方案
核心问题1:sleep(1)缩进错误
你的eventCheck函数中,sleep(1)写在了while True循环的外部,这会导致该线程无限高频执行循环内的代码,完全不休息。它会疯狂抢占锁,让readData线程几乎没有机会获取锁去更新dataRef,最终dataRef的值几乎不会变化,自然每次打印的dataRefPrevious和dataRefActive始终相同。
核心问题2:字典的引用赋值特性
Python中字典是引用类型,你直接使用dataRefPrevious = dataRef或dataRefPrevious = dataRefActive的赋值方式,只是让变量指向同一个字典对象,而非复制字典内容。即使readData更新了dataRef,如果simulate_external_data_source返回的是同一个字典对象(而非每次生成新字典),dataRefPrevious和dataRefActive也会指向同一个对象,看起来始终相同。
修复代码
import threading from time import sleep import random dataRef = {} data_lock = threading.Lock() def simulate_external_data_source(): # 确保每次返回新的字典对象,而非复用同一个 return {"value": random.randint(0, 100)} def readData(): global dataRef while True: dataRefsValues = simulate_external_data_source() with data_lock: dataRef = dataRefsValues sleep(0.5) def eventCheck(): global dataRef dataRefPrevious = {} while True: with data_lock: # 复制字典内容,而非引用 dataRefActive = dataRef.copy() if dataRefPrevious: print('dataRefPrevious', dataRefPrevious,"\n") print('dataRefActive', dataRefActive, "\n") # 更新历史快照 dataRefPrevious = dataRefActive.copy() # 将sleep放到循环内部,控制执行频率 sleep(1) # 启动线程 threading.Thread(target=readData, daemon=True).start() threading.Thread(target=eventCheck, daemon=True).start() # 主线程保持运行 while True: sleep(1)
修复说明
- 调整
sleep(1)的缩进,让eventCheck线程每秒仅执行一次,给readData留出获取锁更新数据的时间。 - 使用
copy()方法复制字典内容,保存每次数据的快照,避免因引用指向同一对象导致的判断失效。 - 确保
simulate_external_data_source每次返回新的字典对象,保证数据更新时dataRef指向新的内存地址。
内容的提问来源于stack exchange,提问作者wisnia80
相关产品推荐
相关产品推荐

