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

使用Python multiprocessing模块时程序无限挂起无法执行后续代码求助

问题根因

你遇到的是Python multiprocessing模块的经典队列死锁问题,官方文档明确标注了该风险:

如果子进程向队列写入了超出缓冲区上限的数据,且父进程未及时读取队列内容,子进程会阻塞在queue.put()调用上无法退出;此时父进程如果先执行worker.join()等待子进程结束,就会形成双向等待的死锁,程序永远停滞。

你的代码刚好触发了这个场景:你先等待所有子进程join完成,才开始从队列拿数据,每个子进程返回的患者对象列表数据量较大时,队列缓冲区被打满,子进程卡着无法退出,父进程也永远等不到join返回。
另外你代码中还存在不必要的冗余:你声明的是普通multiprocessing.Queue,却搭配了multiprocessing.Manager()上下文,两者没有关联,Manager在这里完全没有发挥作用。

修复方案

调整执行顺序:启动所有子进程后,先读完队列中所有子进程的返回数据,再调用join等待子进程退出即可。

修改后的addClinicalData方法代码
def addClinicalData(self, patients, clinicalTagStr, medcodeTuple=None, numCores=1):
    patientsList = patients.getAllPatients()
    splitList = list(np.array_split(patientsList, numCores))

    queue = multiprocessing.Queue()
    workers = []
    for i in range(numCores):
        workers.append(multiprocessing.Process(target=self.addClinicalDataToPatient,
                                               args=(splitList[i], clinicalTagStr, medcodeTuple, queue)))

    # 先启动所有子进程
    for worker in workers:
        worker.start()
    
    # 先读取所有队列数据,避免子进程阻塞在put
    newPatients = Patients()
    for i in range(numCores):
        patientList = queue.get()
        for patient in patientList:
            newPatients.addPatient(patient)
    
    # 所有数据读取完成后再等待子进程退出
    for worker in workers:
        worker.join()                    

    return newPatients
可选优化方案

你也可以直接使用multiprocessing.Pool实现并行逻辑,不需要自己维护进程和队列,避免手动写队列带来的死锁风险:

from functools import partial

def addClinicalData(self, patients, clinicalTagStr, medcodeTuple=None, numCores=1):
    patientsList = patients.getAllPatients()
    splitList = list(np.array_split(patientsList, numCores))
    # 绑定固定参数
    task_func = partial(self.addClinicalDataToPatientNoQueue, clinicalTagStr=clinicalTagStr, medcodeTuple=medcodeTuple)
    
    with multiprocessing.Pool(numCores) as pool:
        # 直接用map获取所有子进程返回结果,无需手动维护队列
        result_list = pool.map(task_func, splitList)
    
    newPatients = Patients()
    for patientList in result_list:
        for patient in patientList:
            newPatients.addPatient(patient)
    return newPatients

对应的addClinicalDataToPatient方法需要去掉queue参数,直接return newPatientList即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 19:36:04