【问题标题】:Multiprocessing Queue Negative Max Size多处理队列负最大大小
【发布时间】:2015-05-22 23:03:05
【问题描述】:

有一些代码示例为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 的值。负数是否会创建操作系统可能支持的最大队列?是否有任何文档阐明了这个神奇的价值?

【问题讨论】:

    标签: python message-queue python-multiprocessing


    【解决方案1】:

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

    首先,Queue 文档说:

    Queue 实现了queue.Queue 的所有方法,除了task_done()join()

    更早的时候,Exchanging objects between processes:

    Queue 类是queue.Queue 的近似克隆。

    而且,如果您点击链接:

    FIFO 队列的构造函数。 maxsize 是一个整数,用于设置可放入队列中的项目数的上限。一旦达到这个大小,插入将被阻塞,直到队列项目被消耗。如果 maxsize 小于或等于 0,则队列大小是无限的。

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

    您可以为此提交一个文档错误。也许所有的类都应该明确地说“接口与&lt;relevant other class, with link> 完全相同,但下面指定除外”,而不是让您在文档的其他地方找到该信息?


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

    PyInit__multiprocessing_multiprocessing 模块的顶级代码)中,它被动态添加到SemLock 类型的__dict__

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

    信号量可能具有的最大值。

    源 cmets 可能有点混乱。

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

    【讨论】:

    • 另外,multiprocessing.Queue 的文档说:Queue 实现了queue.Queue 的所有方法,除了task_done()join()
    • @EllaShar:我想这和“近克隆”一样好;两者都不算直接保证语义,但它们都非常强烈地暗示它。编辑了答案;谢谢。
    【解决方案2】:

    我似乎找不到 _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 改进文档的一个很好的案例。如果你能这么好。

    文档提示

    我在文档中找不到任何说明负值含义的内容

    它实际上是平台相关的,使用上面的命令获取实际值。

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

    如果 maxsize 小于或等于零,则队列大小是无限的。

    multiprocessing's guide 声明

    Queue 类几乎是 Queue.Queue 的克隆。

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

    血淋淋的细节

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

    是否有任何文档阐明了这个神奇的价值?

    不——如果你真的想知道,你必须按照代码...对于CPython,有这些#include文件multiprocessing.h和平台C库的limits.h,后者最终被@987654326包含@。换言之,SEM_VALUE_MAX 的设置取决于主机平台。

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

    信号量可能具有的最大值。可接受的最小值:_POSIX_SEM_VALUE_MAX

    所以_POSIX_SEM_VALUE_MAX最小值,它又被定义为:

    信号量可能具有的最大值。价值:32767

    【讨论】:

      猜你喜欢
      • 2011-08-19
      • 2014-09-04
      • 2022-12-07
      • 2010-11-24
      • 1970-01-01
      • 2014-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多