我的代码结构如下所示:
Class A:
def __init__(self):
processes = []
for i in range(1000):
p = Process(target=self.RunProcess, args=i)
processes.append[p]
# Start all processes
[x.start() for x in processes]
def RunProcess(self, i):
do something with i...
主要剧本:
myA = A()
我似乎无法让它运行。我收到运行时错误“尝试在启动之前启动新进程 当前流程已完成其自举阶段。“
如何让多个处理工作?如果我使用线程,它运行正常,但它和顺序一样慢...而且我也担心多次处理也会很慢,因为创建进程需要更长的时间?
有什么好的提示吗?非常感谢提前。
答案 0 :(得分:6)
我可以在您的代码中看到一些语法问题:
args
Process
期待一个元组,你传递一个整数,请将第5行更改为:
p = Process(target=self.RunProcess, args=(i,))
list.append
是一种方法,传递给它的参数应该包含在()
中,而不是[]
中,请将第6行更改为:
processes.append(p)
正如@qarma指出的那样,在类构造函数中启动进程并不是一个好习惯。我将按如下方式构造代码(调整您的示例):
import multiprocessing as mp
from time import sleep
class A(object):
def __init__(self, *args, **kwargs):
# do other stuff
pass
def do_something(self, i):
sleep(0.2)
print('%s * %s = %s' % (i, i, i*i))
def run(self):
processes = []
for i in range(1000):
p = mp.Process(target=self.do_something, args=(i,))
processes.append(p)
[x.start() for x in processes]
if __name__ == '__main__':
a = A()
a.run()
答案 1 :(得分:4)
它应该简化您使用Pool
的内容。就速度而言,启动流程确实需要时间。但是,使用Pool
而不是njobs
运行Process
应该与使用进程运行它一样快。 Pool
的默认设置(如下所示)是使用可用的最大进程数(即您拥有的CPU数),并在作业完成后立即为工作人员提供新的工作。你不会得到njobs
- 并行方式,但是你可以获得你的CPU可以处理的并行性,而无需超额订阅处理器。我正在使用pathos
,其分叉为multiprocessing
,因为它比标准multiprocessing
更强大......而且,我也是作者。但你可以使用multiprocessing
来实现这个目标。
>>> from pathos.multiprocessing import ProcessingPool as Pool
>>> class A(object):
... def __init__(self, njobs=1000):
... self.map = Pool().map
... self.njobs = njobs
... self.start()
... def start(self):
... self.result = self.map(self.RunProcess, range(self.njobs))
... return self.result
... def RunProcess(self, i):
... return i*i
...
>>> myA = A()
>>> myA.result[:11]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
>>> myA.njobs = 3
>>> myA.start()
[0, 1, 4]
在Pool
内启动__init__
是一个奇怪的设计。但是如果你想这样做,你必须得到self.result
之类的结果......你可以使用self.start
进行后续调用。
在此处获取pathos
:https://github.com/uqfoundation
答案 2 :(得分:0)
实际的解决方法是打破你的课程,例如:像这样:
class A:
def __init__(self, ...):
pass
def compute(self):
procs = [Process(self.run, ...) for ... in ...]
[p.start() for p in procs]
[p.join() for p in procs]
def run(self, ...):
pass
pool = A(...)
pool.compute()
当你在__init__
内分叉一个进程时,类实例self
可能无法完全初始化,因此要求子进程执行self.run
是很奇怪的,尽管从技术上讲,是的,它是可能的。
如果不是这样,那么这听起来像是这个问题的一个例子: