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

使用multiprocessing Queue时程序为何挂起?

问题:Python多进程Queue程序挂起无输出

正在探索multiprocessing模块用法,参考某指南的代码运行时出现Runtime错误,添加if __name__ == "__main__":块后,程序仅打印两个进程中的print语句,随后挂起,无队列元素输出。

原指南代码:

import multiprocessing as mp

def addPositive(queue):
    print("I am in addPositive.")
    for i in range(1, 100):
        queue.put(i)

def addNegative(queue):
    print("I am in addNegative.")
    for i in range(-100, 0):
        queue.put(i)

myQueue = mp.Queue()
process1 = mp.Process(target=addPositive, args=(myQueue,))
process2 = mp.Process(target=addNegative, args=(myQueue,))
process1.start()
process2.start()
process1.join()
process2.join()
while myQueue:
    print(myQueue.get(), end=",")
myQueue.close()

修改后的代码:

import multiprocessing as mp


def addPositive(queue):
    print("I am in addPositive.")
    for i in range(1, 100):
        queue.put(i)


def addNegative(queue):
    print("I am in addNegative.")
    for i in range(-100, 0):
        queue.put(i)


def run():
    myQueue = mp.Queue()
    process1 = mp.Process(target=addPositive, args=(myQueue,))
    process2 = mp.Process(target=addNegative, args=(myQueue,))
    process1.start()
    process2.start()
    process1.join()
    process2.join()
    while myQueue:
        print(myQueue.get(), end=",")
    myQueue.close()

 
if __name__ == "__main__":
    run()

期望输出类似:

1,2,3,4,5,6,7,8,9,10,-100,-99,-98,...

环境信息:Python 3.9.6,macOS Monterey 12.4


问题原因与解决方法

核心问题

while myQueue:的判断逻辑错误——multiprocessing.Queue对象在布尔判断中始终返回True,不会因为队列空了变为False。当队列中的所有元素被取完后,myQueue.get()会进入阻塞状态,等待新元素加入,导致程序无限挂起。

解决方案

方案1:按已知元素总数循环取数

既然知道两个进程总共会向队列中放入99+99=198个元素,直接循环对应次数即可:

import multiprocessing as mp


def addPositive(queue):
    print("I am in addPositive.")
    for i in range(1, 100):
        queue.put(i)


def addNegative(queue):
    print("I am in addNegative.")
    for i in range(-100, 0):
        queue.put(i)


def run():
    myQueue = mp.Queue()
    process1 = mp.Process(target=addPositive, args=(myQueue,))
    process2 = mp.Process(target=addNegative, args=(myQueue,))
    process1.start()
    process2.start()
    process1.join()
    process2.join()
    
    # 循环固定次数取完所有元素
    for _ in range(198):
        print(myQueue.get(), end=",")
    
    myQueue.close()


if __name__ == "__main__":
    run()

方案2:用结束标记判断队列处理完成

在每个进程结束前向队列放入一个特殊标记(比如None),主进程循环取元素,直到收集到所有进程的结束标记:

import multiprocessing as mp


def addPositive(queue):
    print("I am in addPositive.")
    for i in range(1, 100):
        queue.put(i)
    queue.put(None)  # 放入结束标记


def addNegative(queue):
    print("I am in addNegative.")
    for i in range(-100, 0):
        queue.put(i)
    queue.put(None)  # 放入结束标记


def run():
    myQueue = mp.Queue()
    process1 = mp.Process(target=addPositive, args=(myQueue,))
    process2 = mp.Process(target=addNegative, args=(myQueue,))
    process1.start()
    process2.start()
    
    finished_processes = 0
    while finished_processes < 2:
        item = myQueue.get()
        if item is None:
            finished_processes += 1
        else:
            print(item, end=",")
    
    process1.join()
    process2.join()
    myQueue.close()


if __name__ == "__main__":
    run()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 07:54:19