Python multiprocessing spawn模式下子进程终止后主进程无法继续执行问题
问题场景
- 开发目标:Python中通过spawn启动模式创建独立子进程执行指定函数,借助多进程队列将子进程的运行进度回传至主进程,主进程需等待子进程完全终止后,再继续执行后续业务逻辑。
- 初始实现代码:
import multiprocessing as mp import time def foo(queue): for i in range(10): queue.put(i) time.sleep(1) if __name__ == '__main__': mp.set_start_method('spawn') queue = mp.Queue() p = mp.Process(target=foo, args=(queue,)) p.start() while p.is_alive(): print("ALIVE") print(queue.get()) time.sleep(0.01) print("Process finished")
- 异常表现:代码实际运行输出为:
ALIVE 0 ALIVE 1 ALIVE 2 ALIVE 3 ALIVE 4 ALIVE 5 ALIVE 6 ALIVE 7 ALIVE 8 ALIVE 9 ALIVE
运行至上述输出节点后,主进程卡死,既不再循环打印"ALIVE"日志,也无法执行循环外的"Process finished"打印逻辑,无后续响应。
问题根因
multiprocessing.Queue 的get()方法默认采用阻塞读取模式:当队列为空时,会一直挂起当前执行流,直到有新元素入队才会返回结果,不会主动感知子进程的运行状态。
当子进程执行完最后一次queue.put(9)、主进程取出队列里的最后一个进度值后,主进程再次调用queue.get()时队列已经为空,就会永久阻塞在这个方法调用上,不再回到while循环的条件判断步骤,也就无法触发后续的子进程状态校验、退出逻辑判断。
修复方案
调整循环内的读取逻辑,在执行queue.get()前先判断队列是否有可读元素,跳过无意义的阻塞等待,调整后的核心代码段为:
while p.is_alive(): if not queue.empty(): print(queue.get()) time.sleep(0.01)
该逻辑下,主进程会以10ms的小间隔轮询校验子进程运行状态、检查队列是否有进度值:有可读数据时取出打印,没有就短暂休眠;直到子进程完全退出、p.is_alive()返回False,循环自然终止,顺畅接续执行后续业务逻辑。
内容的提问来源于stack exchange,提问作者dunky11
相关产品推荐
相关产品推荐

