【问题标题】:python multiprocessing.Process.Manager not producing consistent results?python multiprocessing.Process.Manager 没有产生一致的结果?
【发布时间】:2012-10-21 12:39:06
【问题描述】:

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

【问题讨论】:

  • (你没有进行任何类的同步。这是一个非常基本的问题,“在你开始编码之前先浏览一本关于进程同步的大学教科书”之类的问题。 )
  • 通过同步,没有“似乎大部分工作”这样的事情。对于竞争条件错误,没有预期的错误行为可预测错误行为。
  • 另外,您会从哪里获得这种印象?对列表执行任何单个操作可能是安全的(例如append()),但self.A[i] = self.A[i] + 1显然是两个操作,__getitem__和@ 987654327@。列表实现无法自动确保在您的代码中实现的一系列操作的原子性。
  • ughhhh,还要记住,人际交往能力和沟通对于成为一名成功的程序员很重要

标签: python multiprocessing python-multiprocessing


【解决方案1】:

正如 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)))

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

【讨论】:

    【解决方案2】:

    通过上面的 cmets 得到了答案,因为以下行导致出现竞争条件:

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

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

    【讨论】:

      猜你喜欢
      • 2023-01-20
      • 1970-01-01
      • 2012-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-10
      • 1970-01-01
      • 2021-09-06
      相关资源
      最近更新 更多