queue no Python: comunique threads

Publicado em: 28/08/2026
Tempo de leitura: 6 minutos
Detailed shot of a Jungle Carpet Python (Morelia spilota cheynei) in its natural habitat.

O módulo queue fornece filas sincronizadas para comunicação segura entre threads. Ele implementa FIFO, LIFO, prioridade e uma fila simples, com operações bloqueantes, timeouts, capacidade máxima e acompanhamento de tarefas. O padrão produtor-consumidor fica mais claro porque os workers trocam mensagens em vez de modificar estruturas compartilhadas diretamente.

Uma fila não torna o processamento automaticamente correto. O programa ainda precisa definir ownership, formato das mensagens, backpressure, tratamento de exceções, encerramento e idempotência. Também é importante distinguir queue.Queue, destinada a threads, de multiprocessing.Queue e asyncio.Queue.

Crie uma fila FIFO

Queue entrega itens na ordem de entrada.

from queue import Queue

fila = Queue()
fila.put("primeiro")
fila.put("segundo")
print(fila.get())

A fila sincroniza o acesso interno entre threads.

Defina capacidade

maxsize limita a quantidade aproximada de itens pendentes.

fila = Queue(maxsize=100)

Uma fila limitada cria backpressure: produtores podem esperar quando consumidores não acompanham.

put bloqueante

Por padrão, put() espera até existir espaço.

fila.put(item, timeout=5)

Com timeout, a operação gera queue.Full se não puder inserir.

put_nowait

put_nowait() tenta inserir imediatamente.

from queue import Full

try:
    fila.put_nowait(item)
except Full:
    registrar_descarte(item)

Defina uma política: esperar, descartar, persistir, reduzir produção ou retornar erro.

get bloqueante

get() espera por um item.

item = fila.get(timeout=2)

Se o prazo terminar, gera queue.Empty.

Não use empty para decidir get

empty(), full() e qsize() são apenas aproximações em ambiente concorrente.

Outra thread pode alterar a fila entre a consulta e a operação. Use get_nowait() ou timeout e trate a exceção.

Produtor e consumidor

from threading import Thread
from queue import Queue

fila = Queue(maxsize=20)


def consumidor():
    while True:
        item = fila.get()
        try:
            processar(item)
        finally:
            fila.task_done()

thread = Thread(target=consumidor, daemon=True)
thread.start()

O finally garante que o contador de tarefas seja atualizado mesmo após erro.

task_done

Cada item retirado com get() deve receber exatamente uma chamada a task_done() quando o trabalho associado terminar.

Chamar mais vezes gera ValueError; esquecer a chamada pode bloquear join() indefinidamente.

join

fila.join() espera até que todas as tarefas inseridas tenham sido marcadas como concluídas.

for item in itens:
    fila.put(item)

fila.join()

Isso não encerra workers. Apenas aguarda o contador de tarefas.

Sentinelas para shutdown

Um objeto especial pode informar que o consumidor deve parar.

PARAR = object()


def consumidor():
    while True:
        item = fila.get()
        try:
            if item is PARAR:
                return
            processar(item)
        finally:
            fila.task_done()

Envie uma sentinela por consumidor quando cada thread retira independentemente.

Ordem do shutdown

Pare os produtores, aguarde a entrada normal, envie sentinelas, espere join() e depois faça join das threads.

Uma ordem incorreta pode deixar trabalho depois das sentinelas ou bloquear produtores em uma fila cheia.

Shutdown moderno

Versões recentes do Python oferecem mecanismos explícitos de shutdown para filas sincronizadas. Eles permitem impedir novas inserções e acordar operações bloqueadas conforme a política escolhida.

Verifique a versão mínima do projeto e trate a exceção específica de fila encerrada. Para compatibilidade ampla, o padrão de sentinelas continua útil.

LifoQueue

LifoQueue entrega o item mais recente primeiro.

from queue import LifoQueue

pilha = LifoQueue()
pilha.put("a")
pilha.put("b")
print(pilha.get())

É útil em buscas ou caches de trabalho recente, mas itens antigos podem sofrer starvation.

PriorityQueue

PriorityQueue entrega o menor valor primeiro e usa heapq internamente.

from queue import PriorityQueue

fila = PriorityQueue()
fila.put((10, "normal"))
fila.put((1, "urgente"))

Use prioridade, contador e payload para evitar comparação entre tarefas.

Empates em PriorityQueue

from itertools import count

contador = count()
fila.put((prioridade, next(contador), tarefa))

O contador preserva estabilidade e impede que objetos não comparáveis sejam avaliados.

SimpleQueue

SimpleQueue oferece uma FIFO não limitada com API menor.

from queue import SimpleQueue

fila = SimpleQueue()
fila.put(item)
item = fila.get()

Use quando não precisa de maxsize, task tracking ou backpressure interno.

Escolha a fila correta

Use Queue para FIFO com capacidade e acompanhamento, LifoQueue para pilha sincronizada, PriorityQueue para prioridades e SimpleQueue para comunicação simples sem limite.

Documente a escolha porque ela afeta fairness e memória.

Exceções no consumidor

Uma falha não deve matar silenciosamente todos os workers.

try:
    processar(item)
except Exception as erro:
    registrar_falha(item, erro)
finally:
    fila.task_done()

Decida entre retry, dead-letter, parada do sistema ou continuação.

Retries

Não reinsira indefinidamente o mesmo item na fila principal.

Mantenha contagem de tentativas, backoff, deadline e uma fila de falhas. Operações com side effects precisam ser idempotentes.

Vários consumidores

Mais threads podem aumentar throughput para I/O, mas também ampliam concorrência contra banco, API e filesystem.

Dimensione workers com base no recurso downstream, não apenas na CPU.

GIL e CPU

Threads normalmente não aceleram trabalho Python puramente limitado por CPU em builds tradicionais.

Para CPU, avalie processos ou extensões que liberem o GIL. Consulte multiprocessing no Python.

Dados mutáveis

A fila transfere uma referência, não uma cópia profunda.

Depois de put(), o produtor deve tratar o objeto como pertencente ao consumidor ou enviar uma estrutura imutável.

Mensagens

Use dataclasses, NamedTuple ou objetos pequenos com campos claros: tipo, payload, ID, tentativa e deadline.

Evite tuplas posicionais longas e dicionários sem esquema.

Backpressure

Uma fila limitada impede crescimento ilimitado, mas produtores bloqueados também podem causar deadlock.

Nunca faça put() bloqueante enquanto mantém um lock que o consumidor precisa.

Fairness

A ordem de wakeup entre threads não deve ser tratada como garantia de justiça perfeita.

Se fairness for requisito de negócio, modele explicitamente classes, cotas ou filas separadas.

Integração com selectors

Workers podem enviar resultados por uma fila; o loop de I/O lê comandos após ser acordado por socketpair ou pipe.

Veja selectors no Python.

Integração com ThreadPoolExecutor

Executores já mantêm uma fila interna. Não adicione outra camada sem necessidade.

Uma fila própria é útil quando você precisa de capacidade, prioridade, mensagens persistentes no processo ou workers customizados.

Timeouts e cancelamento

Timeout em get() permite que a thread verifique uma flag de parada.

while not parar.is_set():
    try:
        item = fila.get(timeout=0.5)
    except Empty:
        continue

Cancelamento de trabalho já iniciado precisa ser cooperativo.

Daemon threads

Threads daemon não impedem o processo de terminar, mas podem ser interrompidas sem cleanup.

Para dados importantes, use threads normais e shutdown explícito.

Observabilidade

Meça tamanho aproximado, tempo de espera, idade do item, taxa de entrada, throughput, falhas e retries.

Não use qsize() como garantia lógica, mas ele pode servir como métrica aproximada.

Segurança

Limite tamanho e quantidade de mensagens. Não coloque callbacks arbitrários recebidos de usuários.

Redija segredos em logs e aplique autorização antes de produzir tarefas.

Testes

Teste fila vazia e cheia, timeout, vários produtores, vários consumidores, exceção, sentinela, retry, shutdown, task_done() e deadlock por lock.

Use eventos de sincronização em vez de sleeps exatos.

Erros comuns

Os erros mais frequentes são usar empty() como garantia, esquecer task_done(), confundir join() da fila com join da thread, enviar poucas sentinelas, permitir fila ilimitada, bloquear segurando lock e compartilhar objetos mutáveis depois de put().

Conclusão

queue oferece comunicação sincronizada e segura entre threads. Use capacidade para backpressure, task_done()/join() para acompanhamento e sentinelas ou shutdown explícito para encerramento.

Consulte a documentação oficial de queue, heapq no Python e selectors no Python.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Conteúdo do artigo

    Artigos relacionados

    Visualização de dados e distribuição estatística para statistics.kde_random no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    statistics.kde_random: gere amostras de uma KDE

    Aprenda statistics.kde_random no Python para gerar amostras a partir de uma distribuição estimada por kernel com controle de suavização, sementes

    Ler mais

    Tempo de leitura: 6 minutos
    13/10/2026
    Ambiente Linux representando namespaces e automação com os.setns no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    os.setns: entre em namespaces Linux com segurança

    Aprenda os.setns no Python para mover processos entre namespaces Linux com segurança, permissões, testes e limpeza adequada.

    Ler mais

    Tempo de leitura: 5 minutos
    13/10/2026
    Computador com código representando cópia de arquivos com Path.copy no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    Path.copy: copie arquivos e pastas com segurança

    Aprenda Path.copy no Python para copiar arquivos e diretórios com controle, segurança, desempenho e compatibilidade.

    Ler mais

    Tempo de leitura: 6 minutos
    12/10/2026
    Código em monitor representando acesso a memória nativa com ctypes.memoryview_at no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    ctypes.memoryview_at: acesse memória sem cópias

    Aprenda ctypes.memoryview_at no Python para acessar memória nativa sem cópias, validar ponteiros e evitar erros perigosos.

    Ler mais

    Tempo de leitura: 7 minutos
    12/10/2026
    Código Python em tela representando EnumDict e enumerações avançadas
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    EnumDict: personalize Enums com validação

    Aprenda EnumDict no Python para personalizar EnumType, validar membros e criar enumerações avançadas com segurança.

    Ler mais

    Tempo de leitura: 5 minutos
    11/10/2026
    Rack de servidores representando balanceamento de conexões com SO_REUSEPORT_LB no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    SO_REUSEPORT_LB: distribua conexões entre workers

    Aprenda SO_REUSEPORT_LB no Python para distribuir conexões entre múltiplos workers com segurança, testes e portabilidade.

    Ler mais

    Tempo de leitura: 6 minutos
    11/10/2026