Python多处理.Process.manager不会产生一致的结果



我已经编写了以下代码来说明我看到的问题。我正在尝试使用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)))

as 毫米指出,这里的问题是self.A[i] = self.A[i] + 1中发生的种族条件。到计算self.A[i] + 1时,self.A[i]可能已经通过另一个过程更改了。

解决问题的一种可能解决方案是将索引传递给父母,然后执行加法。

from multiprocessing import Process, Manager
import random
class MyProc(Process):
    def __init__(self, B, length):
        Process.__init__(self)
        self.B = B
        self.length = length
    def run(self):
        i = random.randint(0, self.length-1)
        self.B.append(i)
if __name__ == '__main__':
    procs = []
    M = Manager()
    a = range(15)
    b = M.list()
    print('A: {0}'.format(a))
    print('sum(A) = {0}'.format(sum(a)))
    for i in range(100):
        procs.append(MyProc(b, len(a)))
    map(lambda x: x.start(), procs)
    map(lambda x: x.join(), procs)
    for i in b:
        a[i] = a[i] + 1
    print('A: {0}'.format(a))
    print('sum(A) = {0}'.format(sum(a)))

将元素附加到数组中只是一个操作,因此避免了比赛条件。

通过上面的评论出现答案,因为以下行:

self.A[i] = self.A[i] + 1

实际上是两个操作,一个__getitem____setitem__

最新更新