2016-08-25 1 views
1

c'est mon code:terme de deux fils en même temps et les deux manipuler la variable simple

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

Je me attends cela me montre 0 (x = 0), mais chaque fois que je l'exécute le résultat est assez différente (moins zéro)
qu'est-ce qui ne va pas?

+0

J'ai essayé d'exécuter votre code; et j'ai immédiatement frappé une erreur de syntaxe sur la troisième ligne. Peut-être que vous essayez d'écrire du code qui fonctionne réellement? – GhostCat

+0

il doit être threading.Thread au lieu de thread.thread – famagusta

+0

Voir [this] (http://stackoverflow.com/questions/1717393/is-the-operator-thread-safe-in-python) poster – FujiApple

Répondre

5

Conditions de la course. Le fonctionnement réel de x += 1 est à peu près:

  1. Charge la valeur de x
  2. Compute x + 1
  3. magasin la valeur calculée à x

Sauf filetage, vous risquez d'être préempté par l'autre thread après l'étape 1 et avant l'étape 3 (que ce soit avant ou après 2 n'a pas d'importance). Si l'autre thread voit la valeur non incrémentée, décrémente cela, alors vous stockez votre valeur incrémentée avant de stocker la valeur décrémentée, vous venez de laisser tomber un incrément; s'ils stockent avant vous, vous avez laissé tomber une diminution.

Vous devez verrouiller l'accès aux variables partagées afin d'assurer que l'opération se comporte atomiquement:

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 

Cela peut introduire un peu de frais généraux, alors d'autres alternatives qui touchent la variable partagée moins peut-être de meilleures options (au détriment d'avoir des comportements différents).

+0

merci. Ça marche –