The*_*ear 15 python multiprocessing
我有一个代码结构,如下所示:
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...
Run Code Online (Sandbox Code Playgroud)
主要脚本:
myA = A()
Run Code Online (Sandbox Code Playgroud)
我似乎无法让它运行.我收到运行时错误" 在当前进程完成其自举阶段之前,已尝试启动新进程. "
如何让多个处理工作?如果我使用线程,它可以正常工作,但它和顺序一样慢...而且我也担心多次处理也会很慢,因为创建进程需要更长的时间?
任何好的提示?提前谢谢了.
我可以在您的代码中看到几个语法问题:
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()
Run Code Online (Sandbox Code Playgroud)
它应该简化您使用的过程Pool
。就速度而言,启动过程确实需要时间。但是,使用a 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]
Run Code Online (Sandbox Code Playgroud)
开始的Pool
内部有点奇怪的设计__init__
。但是,如果要执行此操作,则必须从类似self.result
…的结果中获取结果,并且可以self.start
用于后续调用。
到达pathos
这里:https : //github.com/uqfoundation
一个实际的解决方法是分解你的类,例如:
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()
Run Code Online (Sandbox Code Playgroud)
当您在内部分叉一个进程时__init__
,类实例self
可能不会完全初始化,因此要求子进程执行是很奇怪的self.run
,尽管从技术上来说,是的,这是可能的。
如果不是这样,那么这听起来像是这个问题的一个例子:
http://bugs.python.org/issue11240
归档时间: |
|
查看次数: |
26608 次 |
最近记录: |