concurrent.interpreters.Queue.get()/put() mishandle the timeout argument
还没有人认领这个 Issue。
- 主要语言
- Python
- 星标
- 77.2k
- 派生
- 35.9k
- PR 合并指标
- PR 指标待抓取
描述
concurrent.interpreters.Queue.get() and Queue.put() mishandle their
timeout argument in three related ways.
-
The value is converted with
int(timeout), which truncates a floating-point
timeout to whole seconds. A timeout in the interval[0, 1)becomes a
non-blocking call, and e.g.timeout=1.9waits for only about one second.
queue.Queue, which this queue is meant to be compatible with, accepts a
floating-point number of seconds. -
Because of the same
int()conversion, a small negative float such as
timeout=-0.5is truncated to0and passes thetimeout < 0check
instead of raisingValueError. -
The deadline is computed with
time.time()(the wall clock), while
queue.Queueusestime.monotonic(). The timeout can therefore over- or
under-wait if the system clock is adjusted (NTP step, manual change) during
the call.
Reproducer (3.14.5)
import time
from concurrent.interpreters import create_queue
q = create_queue(maxsize=1)
q.put(b"x") # fill it
start = time.perf_counter()
try:
q.put(b"y", timeout=0.5) # expected: block ~0.5s, then QueueFull
except Exception as exc:
print(type(exc).__name__, f"{(time.perf_counter() - start) * 1000:.1f} ms")
# -> QueueFull 0.0 ms (expected ~500 ms)
q2 = create_queue()
start = time.perf_counter()
try:
q2.get(timeout=0.9) # expected: block ~0.9s, then QueueEmpty
except Exception as exc:
print(type(exc).__name__, f"{(time.perf_counter() - start) * 1000:.1f} ms")
# -> QueueEmpty 0.0 ms (expected ~900 ms)
For comparison, queue.Queue().get(timeout=0.5) blocks for about 500 ms.
The fix is to use the timeout value as given, reject a negative or NaN timeout
with ValueError, and base the deadline on time.monotonic().
Linked PRs
- gh-153006
- gh-154156
- gh-155967
- gh-156018
- gh-156019
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
调研方向
从 concurrent.interpreters.Queue.get() 和 Queue.put() 开始,然后按照 issue 中的描述,将它们的超时处理与 queue.Queue 进行比较。确认小数、负数和 NaN 超时,以及时钟调整时的行为;完成的标准是保留小数等待时间、在指定位置引发 ValueError,并使用单调 deadline。在开始之前检查已链接的 PR,因为相关工作已经在进行中。
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- python
- 领域
- backend
- Issue 类型
- 缺陷
- 难度
- 3/5
- 预计耗时
- 1-2 天
- 活跃度
- 停滞
- 描述清晰度
- 描述清楚
- 新手友好度
- 25/100