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

Python多进程未启动问题:multiprocessing Queue通信异常排查

Python multiprocessing Queue 通信异常问题排查与解决

问题情况

使用Python的multiprocessing模块通过Queue实现主进程与子进程通信时出现异常:子进程func本该向队列写入1到10的数值,最后写入None终止循环,但实际子进程要么未启动,要么陷入阻塞。程序仅输出主进程写入的10到14,且循环无法终止。

复现代码

from time import sleep
import multiprocessing as mp

# 每2秒向队列Q添加一个数字,最后添加None
def func(Q):
    for i in range(1,11):  
        Q.put(i)
        sleep(2)
    Q.put(None)

# 启动子进程添加数字
Q = mp.Queue()
P = mp.Process(target=func, args=(Q,))
P.start()

# 向队列中放入初始值
for n in range(10,15):
    sleep(0.5)
    Q.put(n)

# 等待子进程启动
print("waiting...")
sleep(2)

# 读取队列内容直到遇到None
while True:
    n = Q.get()
    if n is None: break
    print(n)

实际输出

waiting...
10
11
12
13
14

运行环境

  • MacOS Monterey(12.6)
  • Python3.7
  • Macbook Pro(2.9GHz 6核Intel Core i9)

问题原因与解决

从Python3.8开始,MacOS默认采用spawn作为多进程启动方法。原代码未添加if __name__ == '__main__':保护块,spawn模式会启动新的Python解释器,导致进程创建的代码被递归执行,进而引发子进程异常。添加该条件并显式设置启动方法后,问题得到解决。

修复后代码

from time import sleep
import multiprocessing as mp

def func(Q):
    for i in range(1,11):  
        Q.put(i)
        sleep(1)
    Q.put(None)
    
if __name__ == "__main__":
    mp.set_start_method("spawn")
    
    # 启动子进程添加数字
    Q = mp.Queue()
    P = mp.Process(target=func, name="child", args=(Q,), daemon=True)
    P.start()    

    # 向队列中放入初始值
    for n in range(10,15):
        sleep(0.5)
        Q.put(n)

    # 等待子进程启动
    print("waiting...")
    sleep(2)

    # 读取队列内容直到遇到None
    while True:
        n = Q.get()
        if n is None: break
        print(n)

内容的提问来源于stack exchange,提问作者Alain T.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 10:01:19