【发布时间】:2021-10-15 07:03:41
【问题描述】:
我已经找到了这个问题的一些答案,但是我仍然对整个多处理感到困惑。我正在尝试并行化我的程序。为了简化它,我有 2 个类 Problem 和 SubProblem。 Problem 类在 SubProblem 类的 6 个实例上调用 solve_ 方法,目前已连续解决。我相信并行解决这些实例会有所收获。
class Problem():
def __init__(self, data):
self.data = data
self.sub_pbs = {i: SubProblem(data) for i in range(range(6)}
def run(self):
dic_ = self.do_some_analysis() # does some analysis with self.data
result = []
for k, sp in self.sub_pbs.items():
result.append(sp.solve_(dic_, k))
return result
类SubProblem如下:
class SubProblem:
def __init__(self,data):
self.data= self.retrieve_interesting_data(data)
def solve_(self, dic_ k):
solutions = []
# do some stuff and call many other functions and store the result in solutions
return solutions
我尝试并行化我的代码的方式(Problem 类中的run 函数)如下:
import concurrent.futures
def run(self):
dic_ = self.do_some_analysis() # does some analysis with self.data
res = []
with concurrent.futures.ProcessPoolExecutor() as executor:
results = [executor.submit(sp.solve_,dic_, k) for k, sp in self.sub_pbs.items()]
res= [f.result for f in results]
return res
真正的代码要复杂得多。现在以这种方式并行化它之后,事实证明它比串行解决它要慢。我运行分析器,我发现 _thread.Lock 对象的方法 acquire() 花费了很多时间。我认为这可能是因为访问了子问题/进程之间共享的数据。
为了运行solve_,子问题需要两种类型的数据:一些数据所有子问题都应该可以访问它(一种全局数据,是子问题属性的一部分,但也作为参数传递给solve_ 函数),以及特定于每个子问题的其他一些数据,这些数据是子问题属性的一部分,也作为参数传递给 solve 函数。但是,所有这些数据都不会在任何子问题/过程中被修改。
现在我的问题是,我应该如何更改我的代码,以便不会为每个进程复制所有子问题/进程需要访问的数据?有没有关于如何有效地将这些数据传递给进程的提示?
【问题讨论】:
-
您不需要复制太多数据。例如,我有一个图像缩略图比较器。在多处理开始之前,所有缩略图都已加载,并且主线程通过队列将其工作作为对象元组提供给每个进程。 (我使用
multiprocessing.Process,而不是进程池)。在挂钟经过的时间里,多进程版本比线程快大约 6 倍。
标签: python concurrency multiprocessing concurrent.futures