2016-08-25 7 views
1

это мой код:запустить две нити одновременно, и оба они манипулируют одной переменной

import threading 
x=0 
class a(threading.thread) 
    def run(self): 
     global x 
     for i in range(1000000): 
      x+=1 

class b(threading.thread) 
    def run(self): 
     global x 
     for i in range(1000000): 
      x-=1 
def run(): 
    a().start() 
    b().start() 
    //after both thread done 
    print x 
run() 

Я ожидаю, что это показать мне, 0 (х = 0), но каждый раз, когда я запускаю это результат довольно отличается (менее ноль)
что с этим не так?

+0

Я попытался запустить ваш код; и я сразу же ударил синтаксическую ошибку на третьей строке. Может быть, вы пытаетесь опубликовать код, который действительно работает? – GhostCat

+0

его должно быть threading.Thread вместо thread.thread – famagusta

+0

См. [Это] (http://stackoverflow.com/questions/1717393/is-the-operator-thread-safe-in-python) post – FujiApple

ответ

5

условия гонки. Фактическая работа x += 1 примерно:

  1. нагрузки значение x
  2. Compute x + 1
  3. магазин вычисленное значение x

За исключением нарезания резьбы, вы можете получить вытеснена другой нить после шага 1 и до шага 3 (независимо от того, будет ли это до или после 2 не имеет значения). Если в другом потоке наблюдается неинкрементное значение, уменьшается, то вы сохраняете свое увеличиваемое значение до того, как оно сохранит уменьшенное значение, вы просто уронили прирост; если они хранят, прежде чем вы это сделаете, вы снизили декремент.

Вы должны заблокировать доступ к общим переменным, чтобы убедиться, что операция ведет себя атомарно:

import threading 
x=0 
xlock = threading.Lock() 
class a(threading.Thread): 
    def run(self): 
     global x 
     for i in range(1000000): 
      with xlock: 
       x+=1 

class b(threading.Thread): 
    def run(self): 
     global x 
     for i in range(1000000): 
      with xlock: 
       x-=1 

Это может ввести совсем немного накладных расходов, так и другие варианты, которые касаются общей переменной менее может быть лучше варианты (за счет разного поведения).

+0

спасибо. оно работает –