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

multiprocessing不使用Pool生成进程且避免僵尸进程的问题排查

问题根因

你遇到的问题是两处逻辑编写错误导致的统计异常,以及一处不规范的传参写法:

  • 第一处错误:在循环替换进程时,你join的是旧进程p,但往joined_list里追加的却是刚创建的新进程list_process[i]的pid,所以最早启动的4个进程的pid永远不会出现在记录列表里,你误以为这些进程没有被join,实际上join操作本身是执行了的,只是记录错了pid。
  • 第二处错误:最后收尾遍历list_process做join的循环里,你直接用了之前外层for i in range(processes)循环结束后残留的i值(固定为3),所以每次往列表追加的都是list_process[3]的pid,才会出现大量重复的6216记录。
  • 额外不规范写法:创建Process时的args参数要求传入元组,你写的args=(targets.pop(0))会被识别为普通表达式而非元组,正确写法应该加末尾逗号:args=(targets.pop(0),),避免后续参数传递异常。
修正后的代码
from multiprocessing import Process
import time

def target(task):
    print(f"Working for {task*2} seconds ...")
    time.sleep(task*2)

if __name__ == '__main__':
    started_count = 0
    joined_count = 0
    joined_list = []
    processes = 4
    list_process = [None] * processes
    targets = [[2] for i in range(10)]

    while targets:
        for i in range(processes):
            p = list_process[i]
            if not (p and p.is_alive()):
                new_p = Process(target=target, args=(targets.pop(0),))
                new_p.start()
                print(new_p.pid)
                started_count += 1
                list_process[i] = new_p
                if p:
                    assert(not p.is_alive())
                    p.join()
                    # 追加旧进程的pid
                    joined_list.append(p.pid)
                    joined_count += 1

    for process in list_process:
        if process:
            process.join()
            # 追加当前遍历到的进程的pid
            joined_list.append(process.pid)
            joined_count += 1

    print(f'Final started count: {started_count}, final joined count: {joined_count}')
    print(joined_list)

修正后joined_list会正确记录所有被join的进程pid,不存在漏join的情况,也不会产生僵尸进程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 08:15:04