设置为无限时,Python Multiprocessing Queue的上限为32768(2 ^ 15)

时间:2019-05-30 12:07:03

标签: python python-3.x python-2.7

我有一个列表,其中包含大约800000个元素(小字符串),这些元素已装入队列,然后由多处理池中的不同工作进程使用。我发现在PyPy和Python(分别为2.7和3.6)中,即使我已将Queue的maxsize显式设置为0,这两种情况下的Queue在任何给定时间都限制为32768个元素,因此阻止了在第32768个元素上。

为什么会这样?我以为如果maxsize <= 0,它们应该是无限的?我已经解决了这个StackOverflow问题Python Queue raising Full even when infinite,但这是这种性质中的唯一问题。还有其他我可能会想念的东西吗?

我已经尝试了多处理队列的实现,在其中我加载了一百万个整数,并且queue.put(val)方法始终在第32768个值上阻塞。

from multiprocessing import Queue
q = Queue(maxsize=0)
for i in range(int(1e7)):
    q.put(i)
    print(i)

我原本希望能够将所有100万个整数插入到Queue中,但事实证明,由于它阻塞在第32768个整数上,因此无法保存所有整数。我很想知道为什么会发生这种情况的细节,上面链接的另一个StackOverflow问题中可能已经回答了这一点,但是似乎做出回答的用户问我们是否正在使用32位Python发行版不是我的情况,因为我在这两种情况下都使用64位Python发行版,如此处所示(对于2.7.13的PyPy,这是我在项目中使用的版本):

Python 2.7.13 (990cef41fe11, Mar 21 2019, 12:15:10)
[PyPy 7.1.0 with GCC 4.2.1 Compatible Apple LLVM 10.0.0 (clang-1000.11.45.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>> import sys;print("%x" % sys.maxsize, sys.maxsize > 2**32)
('7fffffffffffffff', True)

更新:

我注意到一些非常有趣的事情。这是在MacOS上运行队列时发生的,但是我在Linux的docker容器中运行了代码,并且队列一次有效地全部装载了所有800000个元素!看来这与MacOS有关。

1 个答案:

答案 0 :(得分:3)

多处理队列挂起意味着您很可能超过了最大信号量;即OSX无法将其计算在内,并隐式地将您限制为2 ^ 15-1。

我不确定来源的可靠性/最新程度,但这似乎与osx(https://github.com/st3fan/osx-10.9/blob/master/xnu-2422.1.72/bsd/sys/semaphore.h)的最大值是一致的

编辑/校对:

明确尝试使用大于2 ^ 15-1的限制会失败:

>>> Queue(maxsize=2**15)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/multiprocessing/context.py", line 102, in Queue
    return Queue(maxsize, ctx=self.get_context())
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/multiprocessing/queues.py", line 48, in __init__
    self._sem = ctx.BoundedSemaphore(maxsize)
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/multiprocessing/context.py", line 87, in BoundedSemaphore
    return BoundedSemaphore(value, ctx=self.get_context())
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/multiprocessing/synchronize.py", line 145, in __init__
    SemLock.__init__(self, SEMAPHORE, value, value, ctx=ctx)
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/multiprocessing/synchronize.py", line 59, in __init__
    unlink_now)
OSError: [Errno 22] Invalid argument

在您的情况下,您尝试隐式创建无限大小(<= 0)的队列,但是实际上并非如此,并应用了OSX限制:https://github.com/python/cpython/blob/master/Lib/multiprocessing/queues.py#L37