queue.SimpleQueue: fila FIFO segura entre threads

Publicado em: 04/09/2026
Tempo de leitura: 5 minutos
Desenvolvedor trabalhando com filas e threads em Python

queue.SimpleQueue é uma fila FIFO segura para uso entre threads. Ela foi criada para cenários em que você precisa transferir tarefas ou dados de um produtor para um consumidor sem configurar limite de capacidade, sem controlar manualmente locks e sem usar a estrutura mais completa de queue.Queue.

Na prática, SimpleQueue é útil em pipelines, workers, processamento em segundo plano, coleta de eventos, logging assíncrono e comunicação entre partes concorrentes de uma aplicação. Sua API é pequena: você adiciona itens com put() e remove com get().

O que é uma fila FIFO

FIFO significa first in, first out: o primeiro item inserido é o primeiro a sair. Esse comportamento combina bem com tarefas que precisam preservar ordem de chegada.

from queue import SimpleQueue

fila = SimpleQueue()
fila.put("primeiro")
fila.put("segundo")

print(fila.get())
print(fila.get())

O resultado será primeiro e depois segundo. A fila organiza a ordem e também sincroniza o acesso quando várias threads a utilizam.

SimpleQueue versus Queue

queue.Queue oferece recursos adicionais como capacidade máxima, task_done() e join(). Já SimpleQueue é não limitada e não acompanha a conclusão das tarefas. Isso reduz a API e pode diminuir o custo operacional quando esses controles não são necessários.

Escolha Queue quando precisar de backpressure, limite de memória ou coordenação explícita entre tarefas produzidas e concluídas. Escolha SimpleQueue quando precisar apenas de uma passagem thread-safe e direta de objetos.

Produtor e consumidor

Um padrão clássico usa uma thread para produzir dados e outra para consumir.

from queue import SimpleQueue
from threading import Thread

fila = SimpleQueue()

def produtor():
    for numero in range(5):
        fila.put(numero)
    fila.put(None)

def consumidor():
    while True:
        item = fila.get()
        if item is None:
            break
        print(item * 2)

Thread(target=produtor).start()
Thread(target=consumidor).start()

O valor None funciona como sentinela, indicando que não haverá novos itens. Em sistemas reais, prefira um objeto sentinela exclusivo para evitar conflito com dados válidos.

FIM = object()

Bloqueio no get

Por padrão, get() bloqueia até que um item esteja disponível. Esse comportamento evita loops consumindo CPU para verificar repetidamente se a fila está vazia.

Também é possível usar get_nowait(). Quando não há item, a função lança queue.Empty.

from queue import Empty, SimpleQueue

fila = SimpleQueue()
try:
    item = fila.get_nowait()
except Empty:
    print("nenhum item disponível")

O modo não bloqueante é útil quando a thread precisa continuar executando outras atividades.

Não confie em empty para sincronização

O método empty() informa um estado momentâneo. Outra thread pode inserir ou remover um item imediatamente após a verificação. Portanto, não use empty() como garantia de que um get() seguinte não bloqueará.

if not fila.empty():
    item = fila.get_nowait()

Mesmo nesse exemplo, ainda é mais seguro tratar Empty. Em concorrência, condições podem mudar entre duas linhas de código.

Filas e threading

SimpleQueue foi projetada para threads do mesmo processo. Ela não substitui multiprocessing.Queue quando produtores e consumidores estão em processos diferentes.

Para entender melhor threads, veja o artigo sobre execução assíncrona e controle de fluxo no Python. Também vale revisar limpeza segura de recursos com weakref.finalize, pois workers reais frequentemente precisam encerrar arquivos, conexões e sessões.

Processamento de eventos

Uma fila simples pode separar a geração de eventos do trabalho mais pesado.

from queue import SimpleQueue
from threading import Thread

EVENTOS = SimpleQueue()
FIM = object()

def registrar_eventos():
    while True:
        evento = EVENTOS.get()
        if evento is FIM:
            return
        print(f"evento: {evento}")

worker = Thread(target=registrar_eventos)
worker.start()
EVENTOS.put({"tipo": "login", "usuario": 42})
EVENTOS.put(FIM)
worker.join()

Esse desenho reduz o tempo gasto pela thread que cria o evento. O consumidor pode persistir, agrupar ou transmitir informações.

Tratamento de exceções no consumidor

Uma exceção não tratada pode encerrar o worker e deixar itens acumulados. Envolva o processamento em try e registre falhas.

def consumidor_seguro():
    while True:
        item = fila.get()
        if item is FIM:
            break
        try:
            processar(item)
        except Exception as erro:
            registrar_erro(item, erro)

Defina também se itens com falha serão descartados, reenfileirados ou enviados para uma fila de erros. Reenfileirar sem limite pode criar repetição infinita.

Controle de memória

Como SimpleQueue não possui capacidade máxima, um produtor muito mais rápido que o consumidor pode aumentar o uso de memória. Esse é o principal cuidado da estrutura.

Se o volume for imprevisível, use queue.Queue(maxsize=N). O limite faz o produtor esperar e cria backpressure. Para processamento em blocos, o guia sobre itertools.batched no Python mostra como agrupar itens e reduzir chamadas repetitivas.

Múltiplos consumidores

Várias threads podem chamar get() na mesma fila. Cada item será entregue a um consumidor. A distribuição exata depende do escalonamento e não deve ser usada para garantir afinidade de tarefa.

workers = [Thread(target=consumidor_seguro) for _ in range(4)]
for worker in workers:
    worker.start()

Ao finalizar, envie uma sentinela para cada consumidor. Uma única sentinela encerra apenas a thread que a retirar.

Quando não usar

Não use SimpleQueue para comunicação entre máquinas, persistência durável, garantia de entrega após falha do processo ou filas que precisam sobreviver a reinicializações. Nesses casos, considere RabbitMQ, Redis Streams, Kafka ou um serviço gerenciado.

Também não use a estrutura como substituta automática de asyncio.Queue em código assíncrono. O método get() bloqueia a thread e pode travar o event loop.

Testes

Teste ordem FIFO, encerramento por sentinela, exceções e produção concorrente. Evite testes baseados apenas em sleep(), pois eles podem ficar instáveis. Prefira eventos, joins e timeouts controlados.

O artigo sobre StrEnum no Python mostra uma forma útil de representar estados fechados de workers, como aguardando, executando e finalizado.

Boas práticas

Use uma sentinela exclusiva, documente quem encerra a fila, trate exceções no consumidor, monitore crescimento, finalize threads com join() e escolha Queue quando precisar de limite ou acompanhamento de tarefas. Mantenha os objetos da fila pequenos e evite compartilhar estruturas mutáveis que ainda serão alteradas por outra thread.

Referências

Consulte a documentação oficial de queue.SimpleQueue e a documentação do módulo threading.

Conclusão

queue.SimpleQueue é uma solução direta para comunicação FIFO entre threads. Ela cuida da sincronização, mantém uma API pequena e funciona bem quando não há necessidade de limite de capacidade ou rastreamento de conclusão. O ponto decisivo é compreender que a fila é ilimitada: monitore o ritmo entre produtores e consumidores e migre para Queue(maxsize) quando a pressão de memória precisar ser controlada.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Conteúdo do artigo

    Artigos relacionados

    Desenvolvedor trabalhando com enums e código Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    StrEnum no Python: enums como strings

    Aprenda StrEnum no Python para criar enums como strings, validar entradas, serializar JSON e organizar APIs e configurações.

    Ler mais

    Tempo de leitura: 4 minutos
    04/09/2026
    Pastas e diretórios para contextlib.chdir no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    contextlib.chdir: restaure o diretório automaticamente

    Aprenda contextlib.chdir no Python para trocar diretórios temporariamente com segurança, testes confiáveis e restauração automática do caminho.

    Ler mais

    Tempo de leitura: 5 minutos
    03/09/2026
    Monitoramento de desempenho e execução de código Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    sys.monitoring: instrumentação de baixo overhead

    Aprenda sys.monitoring no Python para instrumentar execução com baixo overhead, eventos, callbacks, ferramentas e observabilidade segura.

    Ler mais

    Tempo de leitura: 6 minutos
    03/09/2026
    Desenvolvedor organizando dados com operator.attrgetter no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    operator.attrgetter: ordene objetos por atributos

    Aprenda operator.attrgetter no Python para ordenar, agrupar e transformar objetos por atributos simples ou aninhados com código mais claro.

    Ler mais

    Tempo de leitura: 5 minutos
    02/09/2026
    Programação assíncrona com asyncio.Runner no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    asyncio.Runner: reutilize o event loop com segurança

    Aprenda asyncio.Runner no Python para reutilizar o event loop, controlar contexto, sinais, debug e encerramento assíncrono com segurança.

    Ler mais

    Tempo de leitura: 6 minutos
    02/09/2026
    Compressão de dados binários com Zstandard no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    compression.zstd: Zstandard com streams e dicionários

    Aprenda compression.zstd no Python para compactar dados com Zstandard, usar streaming, dicionários e limites seguros.

    Ler mais

    Tempo de leitura: 7 minutos
    01/09/2026