我正在解决一个问题,这个问题需要多个线程来更改共享的内存。为了更好地理解python中的工作原理,我开发了以下代码来查看是否可以获得竞态条件:
import threading
class A:
def __init__(self):
self.val = 0
def increment(a):
for _ in range(10):
a.val += 1
def main():
a = A()
threads = [threading.Thread(target=increment, args=(a,)) for _ in range(4)]
for t in threads:
t.start()
for t in threads:
t.join()
print(a.val)
if __name__ == '__main__':
main()非常简单的东西。每个线程都应该同时尝试递增a.val,这应该会导致竞态条件,因为该值不受锁保护。然而,事实并非如此。每次运行这段代码时,a.val的打印值都是40。因为有四个线程,并且每个线程递增a.val 10倍,所以这是正确的答案。有人能解释为什么这不会导致竞态吗?
发布于 2021-03-29 06:33:39
它确实会导致竞态条件。您当前的范围不足以评估这一点。实际上,在下一个线程可以启动之前,第一个启动的线程已经完成。
具体的数字将花费足够长的时间,不再是这种情况将取决于您的计算机资源,对我来说,将增量函数修改为更大的界限确实会导致val在每次运行时都是不同的值。
def increment(a):
for _ in range(1_000_000):
a.val += 1发布于 2021-03-29 06:31:47
我换成了for _ in range(100000),每次得到的答案都不一样。
否则,我猜在下一个线程旋转之前计算就完成了?实际上,如果我在t.start()之前添加time.sleep(1),结果是“正确的”。
==
这是评论中提出的解决方案(但不是问题的答案):
class A:
def __init__(self):
self.val = 0
self.lock = threading.Lock()
def __iadd__(self, y):
with self.lock:
self.val += y
return self
def increment(a: A):
for _ in range(100000):
a += 1https://stackoverflow.com/questions/66846774
复制相似问题