我试图通过Manager
接口共享dict,结果似乎不同!有时是{1: 8, 2: 3, 3: 2, 4: 1}
,有时是{1: 6, 2: 3, 3: 2, 4: 1}
,{1: 7, 2: 3, 3: 2, 4: 1}
,等等。这只是计算除数,应该是确定的。。。在
代码在这里:
from multiprocessing import Process, Manager
def div(x,d):
for i in range(1,x):
if x%i == 0:
try:
d[i] +=1
except:
d[i]=1
mgr = Manager()
d = mgr.dict()
w = [Process(target=div,args=(i,d)) for i in range(1,10)]
for k in w:
k.start()
for k in w:
k.join()
print d
您的代码中有一个race condition,就在这里:
考虑如果
d[i]
还不存在,并且两个进程几乎同时到达d[i] += 1
,会发生什么。两者都将引发异常,并且都将执行d[i] = 1
。最终结果:d[i]
是1
,而不是2
。你损失了一个增量!在仔细观察,即使是
d[i] += 1
本身也可能不是原子的,因此对竞争条件是开放的。在内部,d[i] += 1
按以下操作顺序执行:i
处获取值i
处设置值。在这三个操作中的每一个都是原子的,并且是正确的,但是似乎没有什么可以保证整个序列的原子性。如果两个进程试图同时执行相同的
d[i] += 1
,那么其中一个增量可能会由于我上面解释的原因而丢失。在使用共享字典的另一种方法是让每个进程维护自己的计数集,并在最后聚合这些计数集。这样就很难引入细微的bug。它还可以带来更好的性能特性,因为对进程间通信的需求将更少。在
相关问题 更多 >
编程相关推荐