使用concurrent.futures时仅单核心活跃的技术咨询
问题原因分析及解决办法
最核心原因:误用线程池而非进程池
Python的**全局解释器锁(GIL)**会限制同一时刻只有一个线程执行Python字节码。对于求和这类CPU密集型任务,ThreadPoolExecutor无法真正实现多核并行,只是在单个核心上做线程切换,所以系统监控里只会显示单核心活跃。
如果你的代码里用的是concurrent.futures.ThreadPoolExecutor(),换成concurrent.futures.ProcessPoolExecutor()就能让每个子任务跑在独立进程里,充分利用多核资源。
其他需排查的细节
- 子列表划分错误:如果你的等差划分逻辑有问题,比如实际只生成了1个有效子列表,其余子列表为空或数据量极小,也会导致单核心工作。可以打印每个子列表的长度确认,比如用这种正确的划分方式:
def split_into_parts(start, end, parts): step = (end - start + 1) // parts sub_ranges = [] for i in range(parts): s = start + i * step e = s + step - 1 if i != parts-1 else end sub_ranges.append((s, e)) return sub_ranges - 任务提交逻辑错误:如果提交任务时只调用了一次
executor.submit()或executor.map(),没有为每个子列表分配任务,自然也只会用到单核心。检查任务提交的次数是否和子列表数量一致。
修正后的示例代码
import concurrent.futures def calculate_sum(start, end): total = 0 for num in range(start, end + 1): total += num return total if __name__ == "__main__": # 划分1到10^7为4个等差区间 sub_ranges = split_into_parts(1, 10**7, 4) # 使用ProcessPoolExecutor实现多核并行 with concurrent.futures.ProcessPoolExecutor(max_workers=4) as executor: results = executor.map(calculate_sum, [r[0] for r in sub_ranges], [r[1] for r in sub_ranges]) total_sum = sum(results) print(f"最终总和:{total_sum}")
注意:使用ProcessPoolExecutor时,必须把执行代码放在if __name__ == "__main__":块内,避免子进程重复加载主模块代码引发异常。
内容的提问来源于stack exchange,提问作者Lereu
相关产品推荐
相关产品推荐

