即使在同一个线程上运行,你可能也会遇到问题。例如,如果你执行
from config import globalVar
,如果你重新绑定了局部模块中的globalVar,它就会丢失对config模块中对象的引用。
即使你没有这样做,如果变量在各种模块导入时发生更改,很难跟踪实际的导入顺序。
当你添加线程时,由于各种竞争条件,这变得完全无法管理。除了竞争条件(即你的某个线程在另一个线程设置变量之前读取了该变量),或者不正确的导入之外,线程不应以你所描述的方式影响全局变量的可见性。
具有确定性代码的解决方案是使用适合在线程之间交换(和保护)数据的数据结构。
threading
模块本身提供了
Event
对象,可以用于一个线程等待,直到另一个线程更改你所期望的值:
config.py:
changed = Event()
changed.clear()
global_var = 5
工作线程中的模块:
import config
def do_things():
while True:
config.changed.wait()
do_more_things_with(config.global_var)
在主线程上:
import config
config.global_var = 7
config.changed.set()
在上面的代码中,我总是使用点表示法引用 config 中的对象。对于 "event" 对象没有任何影响 - 我可以使用
from config import changed
- 因为我正在处理同一对象的内部状态,它会起作用 - 但如果我使用
from config import global_var
并重新分配它与
global_var = 7
,那只会改变当前模块上下文中的
local_var
名称指向的位置。
config.local_var
仍然引用原始值。
顺便说一下,值得看一下
队列模块和
线程本地数据。
当它仍然不起作用时
另一个看不到更改的可能性是,由于并行性不在您的代码中,而是在另一个库中,它使用
multiprocessing
模块生成进程而不是线程。
如果您期望使用线程并且生成的是 multiprocessing 的进程,则会出现您所描述的问题:全局变量的更改在其他进程中不可见(因为每个进程都有自己的变量,当然)。
如果是这种情况,则可以拥有跨进程同步的(数字型,类型化)对象。检查
Array
和 Value
类以及
multiprocessing Queue
来发送和接收(大多数)任意对象。
(在您的代码中添加一个
import multiprocessing; print(multiprocessing.current_process())
行以确保。无论结果如何,请建议 RandomizedSearchCV 文档维护者明确说明他们对并行性做了什么)
run.py
文件? - Cheyn Shmuel