多处理队列负最大大小

Multiprocessing Queue Negative Max Size

有一些代码示例为 multiprocessing.Queuemaxsize 指定负数,例如

import multiprocessing
queue = multiprocessing.Queue(-1)

我在文档中找不到任何指定负值含义的内容,所以我查看了 multiprocessing.Queue 源代码。

class Queue(object):

    def __init__(self, maxsize=0):
        if maxsize <= 0:
            maxsize = _multiprocessing.SemLock.SEM_VALUE_MAX
        self._maxsize = maxsize
        ...

我似乎找不到 _multiprocessing.SemLock.SEM_VALUE_MAX 的值。负数是否会创建 OS 支持的最大队列?有没有任何文件可以阐明这个神奇的价值?

multiprocessing.Queue 的文档显然没有直接说明这一点,但在两个地方强烈暗示了这一点。

首先,Queue 文档说:

Queue implements all the methods of queue.Queue except for task_done() and join().

更早一点,在 Exchanging objects between processes 中:

The Queue class is a near clone of queue.Queue.

而且,如果您遵循 link:

Constructor for a FIFO queue. maxsize is an integer that sets the upperbound limit on the number of items that can be placed in the queue. Insertion will block once this size has been reached, until queue items are consumed. If maxsize is less than or equal to zero, the queue size is infinite.

所以,是的,-1 被记录为表示无限……虽然可能不是最直接的方式。

您可以就此提交文档错误。也许所有 类 都应该明确地说 "The interface is exactly like <relevant other class, with link> except as specified below",而不是让您在文档的其他地方找到该信息?


由于您实际上问了两个问题,而不是一个,这里定义了 SEM_VALUE_MAX

PyInit__multiprocessing中,_multiprocessing模块的顶级代码,动态添加到SemLock类型的__dict__中。

它设置的值是特定于平台的,但通常是您平台的 SEM_VALUE_MAXINT_MAX。前者在POSIX 2004中定义为limits.h的一部分,只是指定:

The maximum value a semaphore may have.

来源评论可能有点混乱。

我不知道 NetBSD,但 IIRC,旧的 FreeBSD 也做了同样的事情:该值作为有符号整数提供(实际上,它只是一个 #define 预处理器宏,但这使它成为一个 int 类型常量),但使用它的 API 取无符号值。在 C 中,您可以只将 -1 传递给接受 unsigned int 的函数,这与传递 UINT_MAX 相同 (4294967295)。 Python 没有这些转换规则,因此模块只是将 -1 转换为 INT_MAX (2147483647),这样更安全,并且您不会拥有超过 21 亿个信号量。我相信当前的 FreeBSD 及其后代,如 OS X,只给你 USHORT_MAX (32767),这就没有必要了,但可能还有其他 OS 做同样的事情。

I can't seem to find the value for _multiprocessing.SemLock.SEM_VALUE_MAX

试试这个:

python -c "import _multiprocessing; import platform; print platform.platform(), _multiprocessing.SemLock.SEM_VALUE_MAX"

到目前为止找到的具体值(请相应地编辑和更新):

# OSX 10.9.5
Darwin-13.4.0-x86_64-i386-64bit 32767 
# Linux Mint Qiana
Linux-3.13.0-24-generic-x86_64-with-LinuxMint-17-qiana 2147483647
# Fedora
Linux-3.10.0-123.20.1.el7.x86_64-x86_64-with-fedora-21-Twenty_One 2147483647
# Ubuntu Trusty
Linux-3.13.0-45-generic-x86_64-with-Ubuntu-14.04-trusty 2147483647
# Debian 8
Linux-2.6.32.46-i686-with-debian-8.0 2147483647

这可能是 suggest 改进文档的一个很好的例子。如果你能这么好心就好了

文档提示

I could not find anything in the documentation that specifies what a negative value means

它实际上是依赖于平台的,使用上面的命令获取实际值。

虽然似乎没有针对 multiprocessingmaxsize 文档,但标准库的 Queue 文档提供了以下内容:

If maxsize is less than or equal to zero, the queue size is infinite.

multiprocessing's guide指出

The Queue class is a near clone of Queue.Queue.

因此,我认为可以公平地假设您的解释是正确的,即 创建 OS 可能支持的最大队列。其实,我们不必回到假设,这是事实:

血淋淋的细节

如果您想了解 _multiprocessing.SemLock.SEM_VALUE_MAX 在编译时如何确定的详细信息,请继续阅读。

Is there any documentation that clarifies this magic value?

不——如果你真的想知道,你必须遵循代码...对于 CPython,有这些#include 文件multiprocessing.h and the platform C library's limits.h, the latter eventually being included by Python.h。换句话说,SEM_VALUE_MAX 是根据主机平台设置的。

根据 Open Group 关于 limits.h 的文档,它被定义为

The maximum value a semaphore may have. Minimum Acceptable Value: _POSIX_SEM_VALUE_MAX

所以 _POSIX_SEM_VALUE_MAX 最小值 又定义为:

The maximum value a semaphore may have. Value: 32 767