【问题标题】:Python: Multiprocessing Queue.put not working for semi-large dataPython:Multiprocessing Queue.put 不适用于半大数据
【发布时间】:2013-10-08 20:10:40
【问题描述】:

我正在测试模块多处理中队列结构的功能。我不明白为什么这段简单的代码无法针对几乎没有大的数据集终止

代码:

from multiprocessing import Process,Queue

if __name__ == "__main__":

    tobeQueue = Queue()

    for i in range(1,10000):
        tobeQueue.put(i)

本应终止的代码适用于小于等于 10 的 3 个订单的范围...但不适用于高于 3 的 10 订单...

【问题讨论】:

  • 队列有一个 init 参数 maxsize,当它保留为零或无时,会产生一个无限长的队列。我刚刚尝试使用 Python 2.7.5 将 100000 个元素添加到我的计算机上的队列中,并且成功完成。在你的循环中放一个 if i%1000==0: print i` 语句,看看它是否真的是循环的错。不管是什么问题,都不是很明显。

标签: python queue multiprocessing put


【解决方案1】:

啊,我现在知道问题出在哪里了。

from Queue import Queue

from multiprocessing import Queue 

不是同一个队列。多处理 (mp) queue 中有一些特殊代码,允许它在进程之间来回传递值。这是 python GIL 和线程障碍的结果。

What is happening, is the queue will not allow the process it is in to die until it is empty. 特别注意第二个红色突出显示的警告。循环正常完成,队列不允许您的 python 进程终止,因为队列不在共享内存中,就像您对线程所期望的那样。我并不完全熟悉 mp.Queue 背后的过程,但它涉及到在 putget 进程之间对队列中的项目进行腌制。因此,异常消除一个进程可能会导致死锁。

因此您需要使用queue.get() 完全卸载队列,您的进程将按预期终止。

此代码将按您的预期终止:

from multiprocessing import Process,Queue

if __name__ == "__main__":

    tobeQueue = Queue()

    for i in range(1,10000):
        tobeQueue.put(i)

    for i in range(1,10000):
        tobeQueue.get() #remove all 9999 items, allow it to die.

【讨论】:

  • 感谢您对此的大量澄清。但是还是有疑问。然后程序如何正常终止像 10 或 100 这样的数字,即for x in range(1,10) 等。代码适用于范围函数的小值....即小数据集
  • 嗯...这是有趣的行为,不是吗?我怀疑它与不知道其确切大小的队列有关(它没有 len 属性),但我不确定。不幸的是,答案可能在于源头。
  • 是的,真的是不可预知的行为......我希望其他人也对此有所贡献。数据可能会被垃圾收集。我猜收集大量数据需要很长时间。
  • 不,它不是垃圾收集。这绝对是锁定python进程的队列。我认为发生的事情是队列,一旦达到某个阈值,就会使用管道启动thread 以将数据推送到接收进程。所有线程都在产生线程的同一个 python 实例上运行。由于没有人收集它,所以我们会陷入僵局,直到它被清空,或者kill -9它。
猜你喜欢
  • 2020-12-05
  • 1970-01-01
  • 1970-01-01
  • 2016-01-31
  • 1970-01-01
  • 2018-08-16
  • 1970-01-01
  • 1970-01-01
  • 2018-05-07
相关资源
最近更新 更多