2017-02-01 10 views
2

私はグローバル変数を保持している設定ファイルのconfig.pyを持っている、すなわちconfig.pyに私は、モジュールの実行で今すぐ(5がデフォルトです)グローバル変数

# 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) 

これがうまく機能(IE 7が印刷された)が、私は(test.pyで)印刷のための複数のスレッドを使用している場合、それはありませんつまり、スレッドはrun.pyの変更を見ません(つまり、5が出力されます)。

どうすれば解決できますか?

+0

何を与えるのでしょうか? –

+0

@CheynShmuel 5(デフォルト)を表示します。ですから、スレッドはconfig.pyの独自のコピーを作成すると思います。 – machinery

+0

いつ 'run.py'を実行しますか? –

答えて

3

同じスレッドで実行している場合でも、それを実行する際に問題が発生する可能性があります。たとえば、from config import globalVarを代わりに実行した場合、ローカルモジュールでglobalVarを再バインドすると、configモジュール内のオブジェクトへの参照が失われます。

あなたがそれをしなくても、さまざまなモジュールのインポート時に変数の変更が行われた場合、実際のインポート順序を追跡することは非常に困難です。

スレッドを追加すると、すべての種類の競合条件のために、スレッドは100%扱いにくくなります。競合状態(つまり、スレッドの1つが他のスレッドで設定される前に変数を読み込みます)や誤ったインポートによって、スレッドは記述方法のグローバル変数の変更の可視性に影響を与えてはなりません。

確定的コードを持つソリューションは、スレッド間でのそのインターチェンジに適したデータ構造(およびスレッド間のデータ保護)を使用することです。

config.py:

changed = Event() 
changed.clear() 

global_var = 5 

threadingモジュール自体は、あなたが他の変更まで確かにを待つために一つのスレッドのためにあなたが期待している値を使用することができますEventオブジェクトを提供していますワーカースレッドのモジュール:

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_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ドキュメントのメンテナを提案してください)

+0

答えがありがとうございますが動作しません...進捗状況はありません...スレッドは設定の新しいコピーを作成してから、永遠に待っています私はスレッドを生成するRandomizedSearchCVを使用しています。 – machinery

+0

私はそれについて言及しませんでしたが、あなたのアプリケーションが「スレッド処理」の「マルチプロセッシング」instadを使用していれば、まさにそのようなことが起こります。ライブラリがサブプロセスではなくスレッドを生成していますか? – jsbueno

+0

ドキュメントから、RandomizedSearchCVがマルチプロセッシングを使用するかどうかは不明です。マルチプロセッシングでどのように問題を解決できるでしょうか? – machinery