【问题标题】:How to use class methods in Multiprocessing Pool in Python?如何在 Python 的多处理池中使用类方法?
【发布时间】:2023-02-22 12:44:03
【问题描述】:

我提出了一个简单的玩具问题,但潜在的问题是如何在 Python 的多处理池中使用类方法?

class Var:
    
    def __init__(self,val):
        self.val = val
        
    def increment(self):
        self.val +=1 
        
arr = [Var(1) for i in range(1000)]        
def func(x):
    x.increment()

with Pool() as pool:
    results = pool.map(func, arr)

返回的结果是一组None 值。我希望这是因为 func 没有返回任何内容。但是,arr[0] 仍然设置为 1。它没有递增。当然,我可以让方法返回新值。但这不是我正在寻找的解决方案。应该更新对象。

归根结底,我需要并行处理对象。有没有其他方法可以在 Python 中完成?

【问题讨论】:

  • 当然,多处理使用多进程.进程不共享状态。这就像您打开终端并输入命令python myscript.py,然后打开另一个终端并输入另一个python myscript.py
  • 请注意,Python 中的一切都是对象,因此您始终在多处理中使用对象。这与 OOP 或类定义或类似的东西无关。
  • @juanpa.arrivillaga,有道理——你对更新对象有什么建议?

标签: python oop multiprocessing


【解决方案1】:

你写了

def func(x):
    x.increment()

你想写

def func(x: Var) -> int:
    x.increment()
    return x.val

因此它将在孩子中序列化并在父母中接收回来。


我需要并行处理对象。

就“工作”递增整数而言, 在 cPython 解释器下使用此模块是不可行的, 因为序列化/反序列化的成本将主导任何应用程序级别的工作。

就“工作”是其他一些 CS 任务而言, 你提出了一个 XY 问题。 你问我们关于“X”的话题,你已经知道答案 对回应感到不满。 它消耗了你和我们的时间。 也许现在您准备好向我们询问“Y”了。

【讨论】:

  • 不幸的是arr[0] 仍然是 1,这是我的问题的症结所在。在我的提示中,我考虑过在 func 中返回一个值,但我只是将其视为部分解决方案,该对象需要就地更新。
  • 如果您愿意,可以回复x。关键是您不能掩盖在子进程中执行计算的 IPC 成本。 multiprocessing 模块已经仔细考虑了权衡。如果你想使用它,你必须遵守公共 API,在这种情况下,这意味着你绝对不能只返回 None 然后希望最好。 (不,你说的 .val 绝对是不是1,它已递增到 2,但随后您选择丢弃该值,而不是将其返回堆栈和跨进程。)
  • 举个例子:你所做的是“拿一张编号为 1 的论文。让朋友抄纸。朋友越过编号 1,写下 2,然后将纸扔掉。你看看自己的论文,令你沮丧的是, find number 1 changed. 当被问及他的论文发生了什么事时,他只是耸了耸肩。”。正确的场景是“拿一张编号为 1 的论文。让朋友复制论文。朋友跨过编号 1,写下 2,然后让你将其复制回新论文。你满意地看着你的新论文,欣赏它闪亮的新号码 2。”
猜你喜欢
  • 2022-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-17
  • 2020-08-15
  • 2017-06-09
  • 2018-06-11
  • 1970-01-01
相关资源
最近更新 更多