python多处理.Process.Manager没有产生一致的结果?

2024-05-18 09:39:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我写了下面的代码来说明我所看到的问题。我试图使用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)))

Tags: importselfformat列表进程initdefmanager
2条回答

通过上面的评论得到了答案,有一个竞速条件发生,因为下面这条线:

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

实际上是两个操作,一个__getitem__和一个__setitem__

正如millimoose所指出的,这里的问题是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)))

将元素追加到数组中只是一个操作,因此避免了竞争条件。在

相关问题 更多 >