带有悲情的 Python 多处理
Posted
技术标签:
【中文标题】带有悲情的 Python 多处理【英文标题】:Python multiprocessing with pathos 【发布时间】:2014-11-21 11:26:44 【问题描述】:我正在尝试使用 Python 的 pathos 将计算指定到单独的进程中,以便使用多核处理器加速它。我的代码组织如下:
class:
def foo(self,name):
...
setattr(self,name,something)
...
def boo(self):
for name in list:
self.foo(name)
由于我在使用 multiprocessing.Pool 时遇到了酸洗问题,所以我决定尝试一下 pathos。 我尝试过,如先前主题中所建议的那样:
import pathos.multiprocessing
但它导致错误:没有模块多处理 - 我在最新的 pathos 版本中找不到。
然后我尝试修改boo方法:
def boo(self):
import pathos
pathos.pp_map.pp_map(self.foo,list)
现在没有抛出错误,但 foo 不起作用 - 我的类的实例没有新属性。请帮助我,因为在花了一天时间之后,我不知道下一步该去哪里。
【问题讨论】:
【参考方案1】:我是pathos
作者。我不确定您想从上面的代码中做什么。
但是,我也许可以阐明一些观点。下面是一些类似的代码:
>>> from pathos.multiprocessing import ProcessingPool
>>> class Bar:
... def foo(self, name):
... return len(str(name))
... def boo(self, things):
... for thing in things:
... self.sum += self.foo(thing)
... return self.sum
... sum = 0
...
>>> b = Bar()
>>> results = ProcessingPool().map(b.boo, [[12,3,456],[8,9,10],['a','b','cde']])
>>> results
[6, 4, 5]
>>> b.sum
0
所以上面发生的情况是,Bar
实例 b
的 boo
方法被调用,其中 b.boo
被传递给一个新的 python 进程,然后为每个嵌套列表进行评估。可以看到结果是正确的……len("12")+len("3")+len("456")是6,以此类推。
但是,您也可以看到,当您查看b.sum
时,它神秘地仍然是0
。为什么b.sum
仍然为零?好吧,multiprocessing
(以及pathos.multiprocessing
)所做的就是将您通过映射传递到另一个python进程的任何内容COPY......然后调用复制的实例(在并行)并返回调用的方法调用的任何结果。请注意,您必须返回结果,或打印它们,或记录它们,或将它们发送到文件,或以其他方式。它们无法像您预期的那样返回到原始实例,因为它不是发送到其他处理器的原始实例。实例的副本被创建,然后被丢弃——它们每个都增加了sum
属性,但原始的 `b.sum' 保持不变。
不过,pathos
内部计划使上述工作如您所料 - 原始对象 IS 已更新,但它还不能那样工作。
编辑:如果您使用pip
进行安装,请注意pathos
的最新发布版本已有几年历史,可能无法正确安装,或者可能无法安装所有子模块.一个新的pathos
版本正在等待中,但在那之前,最好从 github 获取最新版本的代码,然后从那里安装。主干大部分稳定在开发中。我认为您的问题可能是由于安装中的“新”pip
--“旧”pathos
不兼容,并非所有软件包都已安装。如果pathos.multiprocessing
丢失,这很可能是罪魁祸首。
在此处从 github 获取 pathos
:https://github.com/uqfoundation/pathos
【讨论】:
我在这里遇到了和 OP 一样的问题。我可以做import pathos
,但import pathos.multiprocessing
给了我一个找不到模块的错误。这可能是什么原因?
问题是,我不明白 OP 的问题……由于英语的一些障碍以及最小的代码示例。也许我可以尝试另一种方法。也许所有依赖项都没有安装。你能import processing
吗? from processing.pool import Pool
怎么样? from pathos.helpers import mp_helper
或 from pathos.helpers import ProcessPool
怎么样? import pp
和 from pathos.helpers import pp_helper
呢?
from pathos.helpers import *
给出“没有名为助手的模块”。不知何故,并不是所有的悲情都对我有用,而且似乎是 OP。我是从 pip 安装的,是最新版本。
在包中,我有core、hosts、Launcher、LauncherSCP、LauncherSSH、pp_map、Server、Tunnel、util、XMLRPCRequestHandler、XMLRPCServer。就是这样,没有助手,没有多处理。
@Brideau:我正在将pathos
拆分成几个包(基本上是所有非标准依赖项),以确保所有东西都可以安装pip
。新版本应该很快就会推出。【参考方案2】:
这就是我的处理方法 - 我将函数放在类外部并行运行,并在调用 pool.map 时将对象作为 arg 传递。然后,我返回要重新分配的对象。
from pathos.multiprocessing import ProcessingPool
def boo(args):
b, things = args
for thing in things:
b.sum += b.foo(thing)
return [b, b.sum]
class Bar:
def __init__(self):
self.sum = 0
def foo(self, name):
return len(str(name))
pool = ProcessingPool(2)
b1 = Bar()
b2 = Bar()
print(b1, b2)
results = pool.map(boo, [[b1, [12,3,456]],[b2, ['a','b','cde']]])
b1, b1s = results[0]
b2, b2s = results[1]
print(b1,b1s,b1.sum)
print(b2, b2s, b2.sum)
输出:
(<__main__.Bar instance at 0x10b341518>, <__main__.Bar instance at 0x10b341560>)
(<__main__.Bar instance at 0x10b3504d0>, 6, 6)
(<__main__.Bar instance at 0x10b350560>, 5, 5)
请注意,b1 和 b2 不再与调用 map
之前的相同,因为正如 @Mike McKerns 所述,它们的副本已被传递。但是,它们所有属性的值都是完整的,因为它们被传递、返回和重新分配。
【讨论】:
以上是关于带有悲情的 Python 多处理的主要内容,如果未能解决你的问题,请参考以下文章
如何使用带有 YouTube API 的 Python 多处理进行抓取 [关闭]
带有 RPYC 的多处理 Python “ValueError:酸洗已禁用”
python多处理日志记录:带有RotatingFileHandler的QueueHandler“文件被另一个进程使用”错误