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

Python多线程跨文件全局变量传值始终返回None的解决方案问询

问题根因分析

你遇到的输出始终为None的核心原因有两个:

  • 跨模块全局变量作用域隔离:Python中global关键字声明的变量仅属于当前模块的全局作用域,thread.py里修改的a是thread模块的独立全局变量,和main_thread.py里定义的全局变量a是完全不同的两个对象,因此主程序读到的永远是初始值None。
  • 无锁读写共享变量存在线程安全风险:即使修正了作用域问题,多线程场景下直接读写共享变量不做并发控制,也容易读到脏数据。
可行实现方案

方案1:使用queue.Queue传递数据(推荐)

队列是Python多线程间通信的官方推荐实现,天生线程安全,不需要手动加锁,支持数据缓冲,适合持续传递增量数据的场景。
修改后的代码如下:

main_thread.py

import threading
import time
from queue import Queue
from thread import thread_function

def main ():
    # 初始化队列,maxsize设置缓冲区大小,0表示无限制
    msg_queue = Queue(maxsize=10)
    # 将队列作为参数传入子线程函数
    thread_1 = threading.Thread(target=thread_function, args=(msg_queue,), daemon=True)
    thread_1.start()

    while True:
        # 读取队列中的值,get()为阻塞读,也可使用get_nowait()实现非阻塞读取
        a = msg_queue.get()
        print(a)
        time.sleep(2)

if __name__ == '__main__':
    main()

thread.py

import random
import time

def thread_function(msg_queue):
    while True:
        a = random.randint(1,10)
        # 将生成的值写入队列,put()为阻塞写,满队列时会等待缓冲区空闲
        msg_queue.put(a)
        # 此处模拟实际场景中抓取网站信息的耗时逻辑
        time.sleep(0.5)

该方案特点:

  • 原生线程安全,不需要自行处理锁逻辑
  • 支持缓冲多组历史数据,不会因为主程序读取速度慢导致数据丢失
  • 可通过Queue.task_done()、Queue.join()实现生产消费端的进度同步

方案2:修正后的跨模块共享变量方式

如果你的场景仅需要获取最新状态、不需要保留历史数据,可以通过公共模块承载共享变量,同时加读写锁保证线程安全。
首先新增公共模块common_var.py用于存储共享变量和锁:

import threading
# 共享状态变量
a = None
# 读写锁
lock = threading.Lock()

调整后的main_thread.py

import threading
import time
from thread import thread_function
import common_var

def main ():
    thread_1 = threading.Thread(target=thread_function, daemon=True)
    thread_1.start()

    while True:
        # 加锁读取共享变量
        with common_var.lock:
            print(common_var.a)
        time.sleep(2)

if __name__ == '__main__':
    main()

调整后的thread.py

import random
import time
import common_var

def thread_function ():
    while True:
        a = random.randint(1,10)
        # 加锁修改共享变量
        with common_var.lock:
            common_var.a = a
        time.sleep(0.5)

该方案注意事项:

  • 所有读写共享变量的位置都必须加锁,否则会出现竞态条件,导致读到异常值
  • 仅能获取变量的最新值,主程序读速慢于子线程生产速度时会丢失中间产生的历史值

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 16:15:04