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

多线程环境下共享类属性后无法正确打印数值的解决方法

多线程跨模块共享类实例属性时读取始终为0的问题解决

问题场景

开发了一个按日、按小时统计操作次数的程序,用Data类的daily和hourly实例存储统计值。后台通过多线程运行background函数实现控制台菜单,用来查看、打印或修改变量,但每次从线程中打印类属性时都显示0,而主线程中直接打印能得到正确的更新后的值。

代码复现

module a

class Data():
    def __init__(self, some_count):
        self.some_count = some_count
daily = Data(0)
hourly = Data(0)

module b

from a import daily, hourly
 
def print_data(command):
    if command == "daily":
        print(f"Daily saying hi is: {daily.some_count}")
    if command == "hourly":
        print(f"Hourly saying hi is: {hourly.some_count}")

def background():  # 控制台菜单函数,支持打印类属性
    while True:
        print_data(input())  # 输入命令选择要查看的统计值

module c

import threading
import time
from a import daily, hourly
from b import background

threading1 = threading.Thread(target=background)
threading1.daemon = True
threading1.start()

# 主线程更新统计值,此处直接打印能得到正确值
while True:
    hourly.some_count += 1   
    daily.some_count += 2
    time.sleep(10)  # 简化示例,替换原代码的10000

注:以上为简化示意代码,非直接可运行版本

问题排查

最初怀疑是线程导致实例变异或导入机制问题,核心矛盾点在于:主线程中实例属性更新正常,但后台线程中读取的实例属性始终为初始值0,说明两个线程中访问的可能不是同一个实例,或者导入时的引用出现了隔离。

解决方案

将类声明与实例化操作拆分到独立模块,确保所有模块和线程引用同一个全局实例:

  1. 创建单独的模块(比如class_declaration.py),仅存放Data类的声明:
class Data():
    def __init__(self, some_count):
        self.some_count = some_count
  1. 在统一的实例化模块(比如instance_store.py)中创建全局实例:
from class_declaration import Data
daily = Data(0)
hourly = Data(0)
  1. 所有需要使用实例的模块(module b、module c)统一从instance_store.py导入实例:
# module b 修改后
from instance_store import daily, hourly
# ... 其余代码不变

# module c 修改后
from instance_store import daily, hourly
# ... 其余代码不变

通过这种方式,实现了跨模块与线程的变量共享,解决了属性读取始终为初始值的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 13:50:41