TSM*_*TSM 9 python multiprocessing google-cloud-platform
我正在使用Python的multiprocessing.Pool类在进程之间分配任务.
简单的案例按预期工作:
from multiprocessing import Pool
def evaluate:
do_something()
pool = Pool(processes=N)
for task in tasks:
pool.apply_async(evaluate, (data,))
Run Code Online (Sandbox Code Playgroud)
产生了N个进程,它们不断地完成我传递给apply_async的任务.现在,我有另一种情况,我有许多不同的非常复杂的对象,每个对象都需要进行计算量大的活动.我最初让每个对象根据需要创建自己的multiprocessing.Pool 在它完成工作的时间,但我最终还是遇到了OSERROR具有开放的文件太多,即使我会假设池会得到使用后垃圾回收.
无论如何,我认为最好为这些复杂对象中的每一个共享同一个池进行计算:
from multiprocessing import Pool
def evaluate:
do_something()
pool = Pool(processes=N)
class ComplexClass:
def work:
for task in tasks:
self.pool.apply_async(evaluate, (data,))
objects = [ComplexClass() for i in range(50)]
for complex in objects:
complex.pool = pool
while True:
for complex in objects:
complex.work()
Run Code Online (Sandbox Code Playgroud)
现在,当我在我的一台计算机上运行它(OS X,Python = 3.4)时,它就像预期的那样工作.产生了N个进程,每个复杂对象在每个进程中分配它们的任务.但是,当我在另一台计算机上运行它(运行Ubuntu的Google Cloud实例,Python = 3.5)时,会产生大量进程(>> N),整个程序因争用而停止运行.
如果我查看池以获取更多信息:
import random
random_object = random.sample(objects, 1)
print (random_object.pool.processes)
>>> N
Run Code Online (Sandbox Code Playgroud)
一切看起来都很正确.但显然不是这样.可能会发生什么想法?
UPDATE
我添加了一些额外的日志.为简单起见,我将池大小设置为1.在池中,当任务完成时,我从多处理模块打印current_process(),并使用os.getpid()打印任务的pid.它导致这样的事情:
<ForkProcess(ForkPoolWorker-1, started daemon)>, PID: 5122
<ForkProcess(ForkPoolWorker-1, started daemon)>, PID: 5122
<ForkProcess(ForkPoolWorker-1, started daemon)>, PID: 5122
<ForkProcess(ForkPoolWorker-1, started daemon)>, PID: 5122
...
Run Code Online (Sandbox Code Playgroud)
再次,使用htop查看实际活动,我看到许多进程(每个对象共享多处理池一个)都在消耗CPU周期,因为这种情况正在发生,导致操作系统争用太多,进展非常缓慢.5122似乎是父进程.
1)您的问题包含与您运行的代码不同的代码(有问题的代码语法不正确,根本无法运行)。
2)多处理模块在错误处理/报告工作人员中发生的错误方面非常糟糕。问题很可能出在您未显示的代码中。您显示的代码(如果已修复)将永远工作并消耗 CPU,但不会因打开太多文件或进程而导致错误。