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

    Código Python em um notebook para criar dataclasses dinâmicas
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    make_dataclass decorator: transforme dataclasses

    Aprenda a usar o parâmetro decorator de make_dataclass para validar, registrar e transformar dataclasses dinâmicas no Python.

    Ler mais

    Tempo de leitura: 6 minutos
    23/10/2026
    Estrutura de código e XML para canonicalização com Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    ElementTree canonicalize: normalize XML no Python

    Aprenda ElementTree canonicalize no Python para comparar XML, gerar hashes estáveis e controlar namespaces, espaços e comentários.

    Ler mais

    Tempo de leitura: 5 minutos
    22/10/2026
    Código de programação Python em uma tela
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    T-strings e templatelib: interpolação estruturada

    Aprenda t-strings e string.templatelib no Python para processar interpolações, criar renderizadores seguros e preservar dados estruturados.

    Ler mais

    Tempo de leitura: 6 minutos
    22/10/2026
    Banco SQLite e código Python para exportação seletiva com iterdump
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    SQLite iterdump: crie dumps seletivos no Python

    Aprenda sqlite3.Connection.iterdump com filtro para gerar dumps seletivos, validar dependências e restaurar bancos com segurança.

    Ler mais

    Tempo de leitura: 5 minutos
    21/10/2026
    Código e arquivos representando compressão de dados no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    compression.zstd: Zstandard rápido no Python

    Aprenda a usar compression.zstd no Python para comprimir e descomprimir dados com desempenho, streaming e segurança.

    Ler mais

    Tempo de leitura: 7 minutos
    21/10/2026
    Arquivo de configuração e estrutura de código para ConfigParser no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    ConfigParser: leia INI sem seção no Python

    Aprenda a ler arquivos INI sem cabeçalho usando ConfigParser, com validação, tipos, compatibilidade e escrita segura.

    Ler mais

    Tempo de leitura: 5 minutos
    20/10/2026