我正在运行一个Python3脚本,其中包含3个主要函数。somefunction()
使用子进程从另一个程序 "eval "获取结果。foo()
将Parallel应用于 somefunction()
; bar()
包含一个for循环,调用 foo()
屡次。
from joblib import Parallel, delayed
import subprocess
class Foobar:
def somefunction(self, i):
cmdline = '~/path/eval ' + 'i' # eval is an executable
output = subprocess.check_output(cmdline, shell=True)
return output
def foo(self):
# Parallel
num_cores = multiprocessing.cpu_count()
list = Parallel(n_jobs=num_cores)(delayed(self.somefunction)(i) for i in somerange)
def bar(self):
for i in range(1000):
self.foo()
result = Foobar()
result.bar()
我在一个有10vCPU的Google计算虚拟机实例上运行这个。一开始,所有10个CPU都在运行,需要1分钟的时间来运行 foo()
. 然而,随着时间的推移,运行的CPU数量越来越少,结果是运行5分钟以上的时间。foo()
.
我认为这个问题在某种程度上是由混合使用的下列因素造成的 subprocess
和 Parallel
我试图排除 subprocess
通过改变 somefunction()
如下图,问题就消失了。
def somefunction(self, i):
for k in range(100000):
k += 1
return k
原代码中发生了什么?有什么优雅的方法来重建这个问题?
我终于解决了这个问题,把多处理改为多线程。
Parallel(n_jobs=num_cores)(delayed(self.somefunction)(i) for i in somerange)
改为
Parallel(n_jobs=num_cores, prefer="threads")(delayed(self.somefunction)(i) for i in somerange)