`multiprocessing.Queue` methods have asymmetric behavior
Ninguém assumiu esta issue ainda.
- Linguagem predominante
- Python
- Estrelas
- 77.2k
- Forks
- 35.9k
- Métricas de merge de PRs
- Métricas de PR pendentes
Descrição
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
Guia de contribuição
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Direção de pesquisa
Comece pela documentação de multiprocessing.Queue sobre qsize(), full() e empty(), depois revise a reprodução na issue e as issues relacionadas #87302 e #128186. Verifique a PR vinculada #144832 e determine se o comportamento foi resolvido nela; considera-se concluído quando os métodos da queue se comportam de forma consistente ou quando o comportamento documentado aborda claramente o caso relatado.
Escrita pelo modelo de indexação a partir do texto da issue.
Avaliação
- Stack de tecnologia
- python
- Domínio
- backend, distributed-systems
- Tipo de issue
- Bug
- Dificuldade
- 4/5
- Tempo estimado
- 3-5 dias
- Status de atividade
- Estagnada
- Clareza
- Razoavelmente clara
- Facilidade para iniciantes
- 35/100