我写了下面的代码来说明我所看到的问题。我试图使用Process.Manager.list()
来跟踪一个列表并增加该列表的随机索引。在
每次生成100个进程,每个进程将列表的随机索引递增1。因此,人们期望每次得到的列表的总和都是相同的,对吗?我得到了203到205之间的数据。在
from multiprocessing import Process, Manager
import random
class MyProc(Process):
def __init__(self, A):
Process.__init__(self)
self.A = A
def run(self):
i = random.randint(0, len(self.A)-1)
self.A[i] = self.A[i] + 1
if __name__ == '__main__':
procs = []
M = Manager()
a = M.list(range(15))
print('A: {0}'.format(a))
print('sum(A) = {0}'.format(sum(a)))
for i in range(100):
procs.append(MyProc(a))
map(lambda x: x.start(), procs)
map(lambda x: x.join(), procs)
print('A: {0}'.format(a))
print('sum(A) = {0}'.format(sum(a)))
通过上面的评论得到了答案,有一个竞速条件发生,因为下面这条线:
实际上是两个操作,一个
__getitem__
和一个__setitem__
正如millimoose所指出的,这里的问题是
self.A[i] = self.A[i] + 1
中发生的竞争条件。在计算self.A[i] + 1
时,self.A[i]
可能已经被另一个进程更改了。在您的问题的一个可能的解决方案是将索引传回父级,然后由父级执行加法。在
将元素追加到数组中只是一个操作,因此避免了竞争条件。在
相关问题 更多 >
编程相关推荐