You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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)

修复说明

  1. 调整sleep(1)的缩进,让eventCheck线程每秒仅执行一次,给readData留出获取锁更新数据的时间。
  2. 使用copy()方法复制字典内容,保存每次数据的快照,避免因引用指向同一对象导致的判断失效。
  3. 确保simulate_external_data_source每次返回新的字典对象,保证数据更新时dataRef指向新的内存地址。

内容的提问来源于stack exchange,提问作者wisnia80

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 20:24:53