簡體   English   中英

全局變量跨python中的模塊和線程

[英]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_varfrom config import global_var並用global_var = 7重新分配,僅更改當前模塊上下文中local_var名稱的位置。 config.local_var仍引用原始值。

而且由於您正在研究它,因此值得一看隊列模塊線程本地對象

當它仍然不起作用時

無法看到更改的另一種可能性是,由於並行性不在您的代碼中,而是在另一個庫中,因此它使用multiprocessing模塊而不是線程來生成進程。

如果您期望線程並且擁有多進程生成的進程,那么您遇到的問題將正是您所描述的:全局變量的更改在其他變量中不可見(當然,這是因為每個進程都有自己的變量)。

在這種情況下,有可能具有跨進程同步的(數字,類型化的)對象。 檢查ArrayValue類,以及multiprocessing Queue ,使其能夠發送和接收(主要是)任意對象。

(確保在您的代碼中添加一個import multiprocessing; print(multiprocessing.current_process())行。請確保不依賴於結果,建議RandomizedSearchCV文檔的維護者明確提及他們為並行性所做的工作)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM