You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

M1 Mac中multiprocessing.Pool无法利用全部核心的问题排查

问题:Python多进程池未充分利用CPU核心

我的代码如下:

from multiprocessing.dummy import Pool
def process_board(elems):
  # 执行一些操作
for _ in range(1000):
  with Pool(cpu_count()) as p:
    _ = p.map(process_board, enumerate(some_array))

代码运行时Mac活动监视器截图:
活动监视器

我可以保证len(some_array) > 1000,理论上有足够多的任务分配,但实际CPU核心并未被充分利用。我忽略了什么?

更新:任务分块测试结果

我尝试对任务进行分块,测试不同分块大小的耗时:

# 每个分块的元素数 -> 耗时
# 100 -> 31.9秒
# 50 -> 31.8秒
# 20 -> 31.6秒
# 10 -> 32秒
# 5  -> 32秒

说明:我大约有1000个元素,每块100个元素对应10个分块,测试期间的CPU负载截图:
CPU负载

可以看到,更改分块数量后,仍无法利用剩余的4个CPU核心...


问题排查与解决

  1. 池类型错误:你用的multiprocessing.dummy.Pool是线程池,受Python GIL(全局解释器锁)限制,同一时间仅能有一个线程执行Python代码,完全无法发挥多核CPU的优势。要实现真正的多核并行,必须改用multiprocessing.Pool(进程池)。

  2. 频繁创建销毁池:循环内每次创建新Pool会产生大量进程启停开销,挤占任务执行的CPU时间,导致核心利用率上不去。应该把池的初始化移到循环外部,复用进程资源。

  3. 分块优化无效的原因:线程池下调整分块大小对多核利用没有帮助,只有换成进程池后,分块才会影响任务调度的开销,此时再根据实际情况调整分块大小才有意义。

修正后的代码

from multiprocessing import Pool, cpu_count

def process_board(elems):
    # 执行你的业务操作

# 循环外创建进程池,复用进程资源
with Pool(cpu_count()) as p:
    for _ in range(1000):
        _ = p.map(process_board, enumerate(some_array))

额外提示

  • 如果process_board是IO密集型任务,线程池可以提升效率,但CPU密集型任务必须用进程池或concurrent.futures.ProcessPoolExecutor。
  • 可尝试p.imap_unordered或p.map_async替代p.map,减少任务等待时间,进一步提升核心利用率。

内容的提问来源于stack exchange,提问作者Alberto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 00:05:19