スレッドでのグローバル変数の使用
グローバル変数をスレッドで共有するには?
私のPythonのコード例は
from threading import Thread
import time
a = 0 #global variable
def thread1(threadname):
#read variable "a" modify by thread 2
def thread2(threadname):
while 1:
a += 1
time.sleep(1)
thread1 = Thread( target=thread1, args=("Thread-1", ) )
thread2 = Thread( target=thread2, args=("Thread-2", ) )
thread1.join()
thread2.join()
2つのスレッドで1つの変数を共有する方法がわかりません。
69
3
a
を
thread2のグローバルとして宣言し、その関数にローカルな
a`を変更しないようにすればよいのです。スレッド1
では、
a`の値を変更しようとしない限り、特別なことをする必要はありません(グローバル変数の影となるローカル変数が作成されてしまいます。機能では
はコンパイラによって
assign to a => Create local variable a
と解釈されますが、これは望んでいるものではありません。ローカルの)a が実際に初期化されていないので、おそらくa not initialized
というエラーで失敗します。非常に嫌われている、そして正当な理由のある)
global
キーワードを使えば、次のようにして欲しいものが得られるかもしれません。しかし、一般的には、すぐに手に負えなくなるようなグローバル変数の使用は _避けるべきです。特にマルチスレッドのプログラムでは、
a
がいつ変更されたのかをthread1
が知るための同期メカニズムを持っていない場合、このことが当てはまります。要するに、スレッドは 複雑 であり、2つ(またはそれ以上)のスレッドが同じ値を処理するときに、イベントの発生順序を直感的に理解することは期待できません。言語、コンパイラ、OS、プロセッサ...すべてが役割を果たし、速度や実用性、その他の理由で操作の順序を変更することを決定します。このような場合の適切な方法は、Pythonの共有ツール(lockksや友人)を使用することです。 など)を使うか、あるいは共有する代わりにQueueを使ってデータを通信するのが良いでしょう、例えば以下のように。
例えば、ランニング。
警告!自宅や職場では絶対にやってはいけません!教室でのみ行います;)
セマフォや共有変数などを使って、ラッシュ状態を回避する。
と出力されます。
タイミングが良ければ、
a += 100
の操作はスキップされます。プロセッサは T
a+100
で実行し、104 を取得します。しかし、それを止めて、次のスレッドに飛びます。 ここで、T+1において、古いaの値であるa == 4
を使って、a+1
を実行します。 そこで、5を計算します。 (T+2の時点で)スレッド1にジャンプバックして、メモリに `a=104
を書き込みます。 今度はスレッド2に戻って、時間はT+3で、a=5
をメモリに書き込みます。 ほら!次のプリント命令では、104ではなく5がプリントされます。これは非常に厄介なバグで、再現して捕まえる必要があります。