1
import threading

x = 0;

class Thread1(threading.Thread):
    def run(self):
        global x
        for i in range(1,100000):
            x = x + 1

class Thread2(threading.Thread):
    def run(self):
        global x
        for i in range(1,100000):
            x = x - 1

#create two threads
t1 = Thread1()
t2 = Thread2()

#start the threads
t1.start()
t2.start()

#wait for the threads to finish
t1.join()
t2.join()

print x;

これを複数回実行すると、異なる出力が生成されます。一部は負で、一部は正です。2つのスレッドが同じグローバルxを使用しているためですか?理由がわかりません。すべてのほこりが落ち着いた後、正味の効果(出力)を同じにすべきではありませんか?

4

3 に答える 3

3

必ずしも。次の一連のイベントを想像してみてください。プログラムが少し実行された後、正確な瞬間から始めます。Thread1とは両方ともループThread2内にあり、forx = 0

  1. Thread1コントロールがあります。;xの値を決定するためにアクセスします。であるため、結果は。でも...x + 1x01
  2. 割り当てを完了する前Thread1に、制御はに渡されThread2ます。xまだ0です。
  3. Thread2今アクセスしxます。はまだであるためx - 1、を計算します。スレッドのタイミングが予測できないため、に割り当てて操作を完了できます。-1x0-1x
  4. コントロールがに戻りますThread1。の値はすでに計算されていx + 1ます1。に割り当て1ますx

両方のスレッドが反復を完了し、の値はであるx必要があります0が、実際の値は1です。

于 2012-12-01T22:31:52.683 に答える
2

これは、マルチスレッドコンピューティングにおける典型的な同時実行の問題です。各スレッドは、メモリからxの現在の値を読み取り、それを変更してから、書き戻す必要があります。スレッド1が値を読み取ると、スレッド2が値を更新し、スレッド1が値を書き戻すと、スレッド2の更新がキャンセルされます。これが、セマフォなどの適切な同期構造を常に使用する必要がある理由です。

于 2012-12-01T22:33:14.307 に答える
1

これは古典的な競合状態です。Wikiには、この状況についての適切な説明があります。

于 2012-12-01T22:29:37.213 に答える