Python 多处理从模块或类内启动,而不是从main()启动
我想使用Python的多处理单元来有效地利用多个cpu来加快我的处理速度 所有这些似乎都可以运行,但是我想从类内部,在程序深处的子模块中运行Python 多处理从模块或类内启动,而不是从main()启动,python,multithreading,multiprocessing,Python,Multithreading,Multiprocessing,我想使用Python的多处理单元来有效地利用多个cpu来加快我的处理速度 所有这些似乎都可以运行,但是我想从类内部,在程序深处的子模块中运行Pool.map(f[item,item])。原因是程序必须首先准备数据,并等待某些事件发生,然后才能处理任何内容 声明只有在语句中才能从运行。我不明白这有什么意义,但还是试了一下,就像这样: from multiprocessing import Pool class Foo(object): n = 1000000 def __init__(s
Pool.map(f[item,item])
。原因是程序必须首先准备数据,并等待某些事件发生,然后才能处理任何内容
声明只有在语句中才能从运行。我不明白这有什么意义,但还是试了一下,就像这样:
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:无法pickle:属性查找
内置。功能失败
我不太明白为什么,因为所有的东西似乎都是可以挑选的。我有以下问题:
不在我的主程序中加入p.map行,这能起作用吗
如果没有,是否可以将“主”程序称为子例程/模块,以使其仍能工作
是否有一些简便的技巧可以从子模块循环回主程序并从那里运行它
我使用的是Linux和Python 2.7,我相信您误解了文档。文档中说的就是要做到这一点:
if __name__ == '__main__':
bar = Bar()
bar.go_all()
因此,您的p.map
行不需要位于“main function”或其他任何内容中。只有实际生成子流程的代码必须被“保护”。由于Windows操作系统的限制,这是不可避免的
此外,传递给Pool.map
的函数必须是可导入的(函数只需按其名称进行pickle处理,然后解释器必须能够导入它们以在传递给子流程时重建函数对象)。因此,您可能应该在全局级别移动do
函数,以避免酸洗错误。ms windows上对多处理
模块的额外限制源于它没有fork
系统调用这一事实。在类似UNIX的操作系统上,fork
创建进程的完美副本,并继续在父进程旁边运行该进程。它们之间唯一的区别是fork
在父进程和子进程中返回不同的值
在ms windows上,多处理
需要使用本机方法启动进程来启动新的Python实例。然后需要将该Python实例置于与“父”进程相同的状态
这意味着(除其他外)Python代码必须是可导入的,而不会产生像尝试启动另一个进程这样的副作用。因此使用如果uuuu name uuu=='uuuu main uuu'
保护。我在Linux上,你是说在这种情况下它不需要在main中吗?@Bastiaan是的,Linux有fork
,它避免了重新导入主模块。您只需从多处理导入池编写一个示例脚本,即可对其进行测试;def f(x):返回x+1;p=池();打印(p.map(f[1,2,3])
(添加导入在linux上它可以精细打印[2,3,4]
在Windows上它会引发异常)。这取决于。默认情况下,Linux上使用启动进程的fork
方法。这没有适用于ms windows的额外限制。但是,如果您使用forkserver启动方法,则会受到与w.r.t.可导入性相同的限制。有关所有输入和输出,请参阅多处理
文档。您指的是该模块的全局级别还是一直到主模块的级别?后者将非常不方便。在全球范围内的子模块工作!并不是说我理解它,。。但是现在它很好。@Bastiaan如果你有一个模块a
,它定义了一个函数def g():def():…
你如何从a
导入f
?你不能。在windows上,由于windows的基本限制,这就是python在执行传递给p.map
的回调时所做的!函数按名称“pickle”,然后发送到子进程。因此,子流程只接收函数名和定义它的模块名,并将其导入,然后执行实际调用并返回结果。但要使其工作,回调必须是可导入的。