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

Python多进程运行异常:耗时超串行或无限运行,疑涉VSCode/Jupyter环境

Python多进程代码异常问题分析与修复

示例1:多进程耗时异常问题

问题根源

  • 计时逻辑错误:启动进程后直接结束计时,未等待子进程执行完成。p1.start()和p2.start()仅完成进程启动操作,此时子进程仍在后台运行,记录的只是进程启动开销,而非任务执行的总耗时。
  • 任务量过小:range(20)的计算量极小,多进程的启动、调度开销远大于并行计算节省的时间,即使修正计时逻辑,也可能出现多进程耗时高于串行的情况。
  • 全局变量无效:子进程会复制主进程的全局变量,results_a和results_b在子进程中的修改不会同步到主进程,这部分结果实际无效。

修复后的代码

import multiprocessing as mp
import time
import math

def calc_one(numbers, result_queue):
    results = []
    for number in numbers:
        results.append(math.sqrt(number **4))
    result_queue.put(results)

def calc_two(numbers, result_queue):
    results = []
    for number in numbers:
        results.append(math.sqrt(number**5))
    result_queue.put(results)

if __name__ == '__main__':
    number_list = list(range(200000))  # 增大任务量体现并行优势
    # 串行计时
    start = time.time()
    res_a = []
    for num in number_list:
        res_a.append(math.sqrt(num**4))
    res_b = []
    for num in number_list:
        res_b.append(math.sqrt(num**5))
    end = time.time()
    print(f"串行处理耗时: {end - start:.4f}秒")

    # 多进程计时
    start = time.time()
    result_queue = mp.Queue()
    p1 = mp.Process(target=calc_one, args=(number_list, result_queue))
    p2 = mp.Process(target=calc_two, args=(number_list, result_queue))
    p1.start()
    p2.start()
    p1.join()  # 等待进程执行完成
    p2.join()
    # 获取结果
    results_a = result_queue.get()
    results_b = result_queue.get()
    end = time.time()
    print(f"多进程处理耗时: {end - start:.4f}秒")

示例2:无限运行问题

问题根源

  • 缺少必要导入:代码直接使用Pool(),但未导入multiprocessing.Pool,需显式导入或通过mp.Pool()调用。
  • 交互式环境特性:Jupyter Notebook/VSCode交互式窗口中,__name__ == '__main__'的执行逻辑与普通脚本不同,子进程启动时会重新执行整个脚本,导致无限创建子进程(类似fork炸弹),进而出现无限运行的情况。

修复后的代码

import multiprocessing as mp
import time

def f(n):
    sum_val = 0
    for x in range(10000):  # 增大任务量
        sum_val += x*x
    return sum_val

if __name__ == "__main__":
    array = [1, 2, 3, 4, 5]

    # 串行计时
    start = time.time()
    result = [f(n) for n in array]
    print(f"串行结果: {result}")
    end = time.time()
    print(f"串行处理耗时: {end - start:.4f}秒")

    # 多进程计时(适配交互式环境)
    start = time.time()
    # 使用spawn启动方式避免fork导致的重复执行问题
    with mp.get_context('spawn').Pool() as p:
        result = p.map(f, array)
    print(f"多进程结果: {result}")
    end = time.time()
    print(f"多进程处理耗时: {end - start:.4f}秒")

环境注意事项

在Jupyter Notebook或VSCode交互式窗口中使用多进程时:

  • 优先使用spawn启动方式(mp.get_context('spawn')),避免fork方式导致的脚本重复执行问题。
  • 建议将多进程逻辑封装成独立函数,仅在if __name__ == '__main__'代码块中调用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 03:24:38