我想使用Python的多处理单元来有效利用多个CPU来加速我的处理速度。
一切似乎都有效,但是我想在程序深处的子模块中的类中运行 Pool.map(f, [item, item])
。原因是程序必须先准备数据并等待某些事件发生才能进行处理。
multiprocessing docs表示您只能从 if __name__ == '__main__':
语句中运行。我不明白其意义,但还是尝试了一下,如下所示:
from multiprocessing import Pool
class Foo(object):
n = 1000000
def __init__(self, x):
self.x = x + 1
pass
def run(self):
for i in range(1,self.n):
self.x *= 1.0*i/self.x
return self
class Bar(object):
def __init__(self):
pass
def go_all(self):
work = [Foo(i) for i in range(960)]
def do(obj):
return obj.run()
p = Pool(16)
finished_work = p.map(do, work)
return
bar = Bar()
bar.go_all()
确实不行!我收到以下错误:
PicklingError: Can't pickle : attribute lookup builtin.function failed
我不太明白为什么,因为一切似乎都是完全可以选择的。我有以下问题:
- 可以在不将 p.map 行放入我的主程序中的情况下使其工作吗?
- 如果没有,“主”程序是否可以作为子例程/模块调用,以便使其仍然可以工作?
- 是否有一些方便的技巧可以从子模块循环回主程序并从那里运行它?
我使用的是 Linux 和 Python 2.7
最佳答案
我相信您误解了文档。文档说的是这样做:
if __name__ == '__main__':
bar = Bar()
bar.go_all()
因此,您的 p.map
行不需要位于您的“主函数”或其他任何内容中。只有实际生成子进程的代码才需要“保护”。由于 Windows 操作系统的限制,这是不可避免的。
此外,您传递给 Pool.map
的函数必须是可导入的(函数仅通过其名称进行腌制,然后解释器必须能够导入它们以在以下情况下重建函数对象:它们被传递到子进程)。因此,您可能应该在全局级别移动您的 do
函数以避免 pickling 错误。
关于python - 从模块或类内部启动多处理,而不是从 main() 启动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42548602/