多处理队列maxsize限制为32767

时间:2011-05-05 16:19:03

标签: python queue multiprocessing max-size

我正在尝试使用多处理编写Python 2.6(OSX)程序,并且我希望使用超过32767项的默认值来填充队列。

from multiprocessing import Queue
Queue(2**15) # raises OSError

Queue(32767)工作正常,但任何较高的数字(例如Queue(32768))都会失败并显示OSError: [Errno 22] Invalid argument

此问题是否有解决方法?

3 个答案:

答案 0 :(得分:3)

一种方法是将multiprocessing.Queue与自定义类包装(仅在生产者方面,或从消费者角度透明地)。使用它,您可以将要分派的项目排队到要包装的Queue对象,并仅将本地队列(Python list()对象)中的内容作为空间提供给multiprocess.Queue变得可用,异常处理在Queue已满时进行限制。

这可能是最简单的方法,因为它应该对代码的其余部分产生最小的影响。自定义类的行为应该像Queue一样,同时隐藏抽象背后的基础multiprocessing.Queue

(一种方法可能是让您的生产者使用线程,一个线程来管理从线程Queue到您的multiprocessing.Queue的调度,以及任何其他线程实际上只是提供线程Queue )。

答案 1 :(得分:2)

我已经回答了原始问题,但我确实想补充说Redis列表非常可靠,Python模块对它们的支持非常容易用于实现类似Queue的对象。它们的优点是允许人们在多个节点(通过网络)以及多个流程上进行扩展。

基本上使用那些你只需为你的队列名称选择一个密钥(字符串)的生产者就可以进入它并让你的工作人员(任务消费者)循环阻止该密钥的弹出。

Redis BLPOP和BRPOP命令都采用密钥列表(列表/队列)和可选的超时值。它们返回元组(键,值)或None(超时)。因此,您可以轻松编写一个事件驱动系统,该系统与 select()的熟悉结构非常相似(但在更高级别)。您唯一需要注意的是缺少密钥和无效的密钥类型(当然,只需使用异常处理程序包装您的队列操作)。 (如果某个其他应用程序在您的共享Redis服务器上停止删除密钥或替换您正在使用的字符串/整数或其他类型的值的队列......那么,您在此时遇到了不同的问题)。 :)

此模型的另一个优点是Redis会将其数据保留在磁盘上。因此,如果您选择允许,您的工作队列可以在系统重启后继续存在。

(当然,如果你真的想这样做,你可以在SQLlite或任何其他SQL系统中实现一个简单的Queue表;只需使用某种自动递增索引进行排序,并使用一列来标记每个项目已经“完成”(消费);但这确实比使用Redis为您“开箱即用”提供的内容更复杂。)

答案 2 :(得分:0)

在MacOSX上为我工作

>>> import Queue
>>> Queue.Queue(30000000)
<Queue.Queue instance at 0x1006035f0>