这是我的代码:

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(x = 0),但每次运行它的结果都大不相同(小于零)

它出什么问题了?

最佳答案

比赛条件。 x += 1的实际操作大致是:

  • 加载x的值
  • 计算x + 1
  • 将计算值存储到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
    

    这可能会带来很多开销,因此,其他一些与共享变量的接触较少的替代方法可能是更好的选择(以具有不同行为的方式为代价)。

    09-18 12:08