运行 两个线程并发并且都操作一个变量
run two thread concurrently and both of them manipulate single variable
这是我的代码:
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
这可能会引入相当多的开销,因此较少接触共享变量的其他替代方案可能是更好的选择(以具有不同行为为代价)。
这是我的代码:
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
这可能会引入相当多的开销,因此较少接触共享变量的其他替代方案可能是更好的选择(以具有不同行为为代价)。