Python - 从非空的multiprocessing.Queue获取Queue.Empty异常

时间:2011-08-02 18:09:26

标签: python performance multiprocessing

我遇到了许多Python用户的相反问题 - 我的程序使用的CPU太少了。我already got help切换到多处理以利用我所有四个工作计算机的核心,结果我看到了真正的性能提升。但这种改善有些不可靠。我的程序的CPU使用率似乎在继续运行时恶化 - 即使有六个进程在运行。添加一些调试消息后,我发现这是因为我正在产生的一些进程(它们都应该运行直到完成)过早死亡。进程运行的方法的主体是一个True循环,唯一的出路是这个块:

try:
    f = filequeue.get(False)
except Empty:
    print "Done"
    return

文件队列在创建子进程之前填充,因此它实际上并不是空的。一旦实际为空,所有进程应在大致相同的时间退出。我尝试在Queue.get调用中添加非零超时(0.05)参数,但这并没有解决问题。为什么我可以从非空队列中获取Queue.empty异常?

2 个答案:

答案 0 :(得分:3)

我建议使用filequeue.get(True)代替filequeue.get(False)。这将导致队列阻塞,直到有更多元素。

但是,在处理完最终元素之后,它将永远阻止。

要解决此问题,主进程可以在每个队列的末尾添加一个特殊的“sentinel”对象。工作人员会在看到这个特殊对象时终止(而不是依赖于队列的空虚)。

答案 1 :(得分:1)

我有一个类似的问题,并且从实验中发现,而不是阅读文档,即使队列非空,get(False)仍然可以虚假地抛出Empty。在我的用例中,工作人员在队列中用完工作时必须退出,因此get(True)是一个非选项。

我的解决方案是这样的:我发现如果在“除了Empty:”块之外,我检查队列确实是空的(),它可以工作 - 除非队列真的为空,否则empty()不会返回True。

我使用的是Python 2.7。