python / python/cpython

`multiprocessing.Queue` methods have asymmetric behavior

未關閉
#142,837 2 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

還沒有人認領這個 Issue。

stdlib topic-multiprocessing type-bug
主要語言
Python
星號
77.2k
分支
35.9k
PR 合併指標
PR 指標待擷取

描述

Bug report

Bug description:

Currently, the qsize() and full() methods rely on the semaphore value (they change their result immediately after the put operation is performed). However, the empty() method relies on the underlying pipe's readiness, which violates user expectations (since similar queue.Queue methods have symmetric behavior) and leads to the following:

#!/usr/bin/env python3

import sys
import time

from multiprocessing import Process, Queue, set_start_method

CONSUMERS = 100  # any sufficiently large number
ITEMS = CONSUMERS * 100  # should result in exceeding the underlying pipe
DELAY = 1  # "infinitesimal", but it can actually be as large as you like


def consume(queue):
    for _ in range(ITEMS // CONSUMERS):
        if queue.empty():  # it should never be printed, but it will be
            print("EMPTY!")

        queue.get()


def main():
    queue = Queue()

    for i in range(ITEMS):
        queue.put(i)

    time.sleep(DELAY)
    assert queue.qsize() == ITEMS

    consumers = [
        Process(target=consume, args=[queue], daemon=True)
        for _ in range(CONSUMERS)
    ]

    for consumer in consumers:
        consumer.start()

    for consumer in consumers:
        consumer.join()


if __name__ == "__main__":
    set_start_method("fork")
    sys.exit(main())

The problem was initially noticed in one Stack Overflow question, when the queue was considered empty despite having a sufficiently large number of items. I have only cited one case, but in fact the problem will always occur when buffer flushing is too slow (especially if any complex objects are serialized).

I decided to mark this as a bug, as this behavior can be fixed as a result of solving #87302. Otherwise, I think clarifying this point in the documentation may also be sufficient.

Related (implicitly used in the above code to reproduce): #128186.

CPython versions tested on:

3.9, 3.10, 3.11, 3.12, 3.13, 3.14

Operating systems tested on:

Linux

Linked PRs
  • gh-144832

貢獻指南

開啟貢獻指南

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

研究方向

先查看 multiprocessing.Queue 中關於 qsize()、full() 和 empty() 的文件,然後檢查 issue 中的重現以及相關 issue #87302 和 #128186。檢查連結的 PR #144832,並判斷其中是否已解決該行為;完成的標準是 queue 方法的行為一致,或文件中說明的行為明確涵蓋所回報的情況。

由索引模型根據 Issue 內容生成。

評估

技術堆疊
python
領域
backend, distributed-systems
Issue 類型
缺陷
難度
4/5
預估耗時
3-5 天
活躍度
停滯
描述清晰度
基本清楚
新手友好度
35/100

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。