1

我编写了以下代码来说明我看到的问题。我正在尝试使用 aProcess.Manager.list()来跟踪列表并增加该列表的随机索引。

每次产生 100 个进程时,每个进程都会将列表的随机索引增加 1。因此,人们会期望结果列表的 SUM 每次都相同,对吗?我得到介于 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)))
4

2 回答 2

3

正如millimoose指出的那样,这里的问题是发生在self.A[i] = self.A[i] + 1. 在计算出时间时self.A[i] + 1self.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)))

将元素附加到数组只是一种操作,因此避免了竞争条件。

于 2012-10-31T22:59:16.583 回答
1

答案是通过上面的评论得出的,因为以下行而发生了竞争条件:

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

实际上是两个操作,a__getitem__和a__setitem__

于 2012-10-31T22:58:44.517 回答