gpt4 book ai didi

python - python中跨模块和线程的全局变量

转载 作者:太空宇宙 更新时间:2023-11-03 15:58:15 25 4
gpt4 key购买 nike

我有一个配置文件 config.py,它包含一个全局变量,即在 config.py 中我有(默认为 5)

# config.py
globalVar = 5

现在在模块 run.py 中设置全局变量,然后调用打印函数:

# run.py
import config
import test
config.globalVar = 7
test.do_printing()

# test.py
import config
def do_printing():
print(config.globalVar)

这很好用(即打印 7)但是如果我使用多个线程进行打印(在 test.py 中)它就不再工作了,即线程看不到 run.py 所做的更改(即 5 是打印)。

如何解决?

最佳答案

即使在同一个线程上运行,您也可能会遇到问题。例如,如果您改为执行 from config import globalVar,如果您在本地模块中重新绑定(bind) globalVar,它只会丢失对 config 模块中对象的引用。

即使您不这样做,如果在导入各种模块时对变量进行了更改,也很难跟踪实际的导入顺序。

当您添加线程时,由于各种竞争条件,这将变得 100% 难以管理。除了竞争条件(即您的一个线程在另一个线程上设置变量之前读取变量)或不正确的导入之外,线程不应以您描述的方式影响全局变量更改的可见性。

拥有确定性代码的解决方案是使用适合跨线程交换(以及跨线程数据保护)的数据结构。

threading 模块本身提供了 Event您可以使用一个线程确定等待另一个线程更改您期望的值的对象:

配置文件:

changed = Event()
changed.clear()

global_var = 5

工作线程中的模块:

import config

def do_things():
while True:
config.changed.wait() # blocks until other thread sets the event
do_more_things_with(config.global_var)

在主线程上:

import config

config.global_var = 7
config.changed.set() # FRees the waiting Thread to run

请注意,在上面的代码中,我总是用点号来引用配置中的对象。这对“事件”对象没有影响——我可以from config import changed——因为我正在处理同一个对象的内部状态,它会起作用——但如果我从 config import global_var 并使用 global_var = 7 重新分配它,这只会更改当前模块上下文中的 local_var 名称指向的位置。 config.local_var 仍然引用原始值。

因为您正在使用它,所以值得一看 queue module , 以及 thread-local对象

还是不行的时候

另一种看不到更改的可能性是,由于并行性不在您的代码中,而是在另一个库中,它正在生成带有 multiprocessing 的进程。模块而不是线程。

如果您期望线程并拥有多进程生成的进程,那么您遇到的问题正是您所描述的:对全局变量的更改在其他进程中不可见(当然,这仅仅是因为每个进程都有自己的变量)。

如果是这种情况,则可能具有跨进程同步的(数字,类型)对象。检查Array and Value类,和 multiprocessing Queue能够发送和接收(大部分)任意对象。

(添加 import multiprocessing; print(multiprocessing.current_process()) 行到您的代码中以确保。独立于结果,请建议 RandomizedSearchCV 文档的维护者明确提及它们是什么为并行做)

关于python - python中跨模块和线程的全局变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41982753/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com