[英]Global variables accross modules and threads in python
我有一個配置文件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
,那么,如果您在本地模塊中重新綁定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
請注意,在上面的代碼中,我總是用點分符號引用config中的對象。 這對於“事件”對象沒有什么區別-我可以from config import changed
來做-因為我正在處理同一個對象的內部狀態,所以它可以工作-但是如果我from config import global_var
做from config import global_var
並用global_var = 7
重新分配,僅更改當前模塊上下文中local_var
名稱的位置。 config.local_var
仍引用原始值。
無法看到更改的另一種可能性是,由於並行性不在您的代碼中,而是在另一個庫中,因此它使用multiprocessing
模塊而不是線程來生成進程。
如果您期望線程並且擁有多進程生成的進程,那么您遇到的問題將正是您所描述的:全局變量的更改在其他變量中不可見(當然,這是因為每個進程都有自己的變量)。
在這種情況下,有可能具有跨進程同步的(數字,類型化的)對象。 檢查Array
和Value
類,以及multiprocessing Queue
,使其能夠發送和接收(主要是)任意對象。
(確保在您的代碼中添加一個import multiprocessing; print(multiprocessing.current_process())
行。請確保不依賴於結果,建議RandomizedSearchCV文檔的維護者明確提及他們為並行性所做的工作)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.