首页 > 解决方案 > 当每个进程需要多个线程时优化python3多处理

问题描述

我有一个包含 12 个项目的列表(每个项目都是一个样本),我需要使用一个函数来分析每个样本。该函数是需要四个线程运行的外部管道的包装器。一些伪代码:

def my_wrapper(sample, other_arg):
    cmd = 'external_pipeline --threads 4 --sample {0} --other {1}'.format(sample, other_arg)
    subprocess.Popen(shlex.split(cmd),stderr=subprocess.PIPE,stdout=subprocess.PIPE).communicate()

以前,我使用循环连续运行每个样本的函数,这有效,但考虑到我的 CPU 有 20 个内核,效率相对较低。示例代码:

sample_list = ['sample_'+str(x) for x in range(1,13)]
for sample in sample_list:
    my_wrapper(sample)

我尝试使用多处理来提高效率。我过去starmap使用multiprocessing. 例子:

with mp.Pool(mp.cpu_count()) as pool:
    results = pool.starmap(my_wrapper, [(sample, other_arg) for sample in sample_list])

当我调用的函数每个进程只需要 1 个线程/核心时,这种方法以前效果很好。但是,在我目前的情况下,它似乎并没有像我天真地期望/希望的那样起作用。有 12 个样本,每个需要用 4 个线程分析,但我总共只有 20 个线程。因此,我希望/希望一次运行 5 个样本(5 个样本 * 每个 4 个线程 = 总共 20 个线程)。相反,所有样本似乎都是同时分析的,使用了所有 20 个线程,尽管需要 48 个线程才能有效。

我如何有效地运行这些样本,以便只有 5 个并行运行(每个进程/作业使用 4 个线程)?我是否需要指定一个块大小,或者我是否带着这个想法吠叫了错误的树?

为模糊的标题和帖子内容道歉,我不知道如何更好地表达它!

标签: python-3.xmultiprocessingstarmap

解决方案


限制多处理池中的核心数量将在运行包装器时节省一些免费运行的核心。这将为您进行分块:

with mp.Pool(mp.cpu_count() / num_cores_used_in_wrapper) as pool:
    results = pool.starmap(my_wrapper, [(sample, other_arg) for sample in sample_list])

推荐阅读