2017-02-01 71 views
2

我有一个配置文件config.py持有一个全局变量,即config.py我有(5是缺省值)在模块运行全局变量进行的跨在Python模块和线程

# config.py 
globalVar = 5 

现在的.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)。

这怎么解决?

+0

是什么给你呢? –

+0

@CheynShmuel它打印5(默认)。所以我认为这些线程创建了自己的config.py副本。 – machinery

+0

你什么时候运行'run.py'? –

回答

3

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

即使您不这样做,如果变量发生在您的各个模块的导入时间,那么很难跟踪实际的导入顺序。

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

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

threading模块本身提供了Event对象,你可以使用一个线程等待肯定直到其他更改你期望的值:

config.py:

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 - 因为我处理的同一对象的内部状态,它的工作 - 但如果我不from config import global_varglobal_var = 7重新分配它,只有改变local_var名称,其中在当前模块的上下文中。 config.local_var仍然引用原始值。

而且因为你是它,这是值得考虑的queue module一看,以及对thread-local对象

当它仍然无法正常工作

另一种可能性为没有看到的变化是, ,因为并行性不在你的代码中,而是在另一个库中,它是用模块而不是线程产生进程。

如果您期待线程和多处理产生的进程,您将遇到的问题正如您所描述的那样:全局变量的更改在其他人看不到(因为每个进程当然都有自己的变量)。

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

(添加import multiprocessing; print(multiprocessing.current_process())行代码是肯定的。独立的结果,请建议RandomizedSearchCV文档的维护者提明确自己在做什么的并行)

+0

感谢您的答案,但它不工作......没有进展......线程似乎创建了一个新的配置副本,然后他们永远等待信号继续...顺便说一句,我使用RandomizedSearchCV产生的线程。 – machinery

+0

我没有提到它,但是如果你的应用程序使用“线程化”的“multiprocessing”instad正是会发生什么 - 尽管API明智,两个模块都是相同的。你确定该库是产生线程而不是子进程吗? – jsbueno

+0

从文档中可以看出,RandomizedSearchCV是否使用多处理并不清楚。如何通过多处理解决问题? – machinery