queue.SimpleQueue: cola FIFO segura entre hilos

Publicado el: 04/09/2026
Tempo de leitura: 5 minutos
Desarrollador trabajando con colas e hilos en Python

queue.SimpleQueue es una cola FIFO segura para comunicar datos y tareas entre hilos. Está pensada para situaciones en las que no necesitas limitar la capacidad, registrar la finalización de cada tarea ni administrar locks manualmente. Su API es pequeña: los productores insertan objetos con put() y los consumidores los retiran con get().

Esta estructura resulta útil en workers, procesamiento en segundo plano, pipelines, registro asíncrono de eventos y comunicación entre componentes concurrentes dentro de un mismo proceso de Python.

Qué significa FIFO

FIFO significa first in, first out: el primer elemento que entra es el primero que sale.

from queue import SimpleQueue

cola = SimpleQueue()
cola.put("primero")
cola.put("segundo")

print(cola.get())
print(cola.get())

El resultado será primero y después segundo. Además de preservar el orden, la cola sincroniza el acceso cuando varios hilos la usan al mismo tiempo.

SimpleQueue frente a Queue

queue.Queue ofrece capacidad máxima, task_done() y join(). SimpleQueue no tiene límite y no registra si las tareas retiradas ya terminaron. Su menor cantidad de funciones es una ventaja cuando solo necesitas transportar objetos de forma segura.

Elige Queue cuando necesites backpressure, memoria limitada o seguimiento de tareas. Elige SimpleQueue cuando solo quieras una comunicación directa y thread-safe.

Patrón productor-consumidor

Un diseño común utiliza un hilo para producir trabajo y otro para procesarlo.

from queue import SimpleQueue
from threading import Thread

cola = SimpleQueue()

def productor():
    for numero in range(5):
        cola.put(numero)
    cola.put(None)

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

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

En este ejemplo, None funciona como centinela para indicar que no llegarán más elementos. En aplicaciones reales conviene usar un objeto único, porque None podría ser un dato válido.

FIN = object()

Comportamiento bloqueante

Por defecto, get() espera hasta que exista un elemento. Esto evita bucles que consultan la cola continuamente y consumen CPU sin necesidad.

También puedes usar get_nowait(). Si la cola está vacía, Python lanza queue.Empty.

from queue import Empty, SimpleQueue

cola = SimpleQueue()
try:
    item = cola.get_nowait()
except Empty:
    print("no hay elementos disponibles")

No uses empty para sincronizar

empty() representa solo una observación momentánea. Otro hilo puede insertar o retirar un elemento inmediatamente después. Por eso, no garantiza que el próximo get() no se bloquee.

Cuando uses acceso no bloqueante, captura Empty. En concurrencia, el estado puede cambiar entre dos instrucciones.

Hilos, no procesos

SimpleQueue está diseñada para hilos del mismo proceso. No sustituye a multiprocessing.Queue cuando productores y consumidores pertenecen a procesos diferentes.

Para revisar conceptos relacionados con control de ejecución, consulta la guía de asyncio.Runner en Python. Los workers que manejan recursos también necesitan una estrategia de limpieza, como se explica en weakref.finalize en Python.

Procesamiento de eventos

Una cola permite separar la creación de un evento de su procesamiento lento.

from queue import SimpleQueue
from threading import Thread

EVENTOS = SimpleQueue()
FIN = object()

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

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

El productor puede continuar rápidamente, mientras el consumidor valida, agrupa, guarda o transmite los eventos.

Excepciones en el consumidor

Una excepción no controlada puede terminar el worker y dejar elementos pendientes. Envuelve el procesamiento en un bloque seguro.

def consumidor_seguro():
    while True:
        item = cola.get()
        if item is FIN:
            break
        try:
            procesar(item)
        except Exception as error:
            registrar_fallo(item, error)

Decide si los elementos fallidos se descartan, se reintentan o se envían a una cola de errores. Los reintentos ilimitados pueden crear un bucle infinito, por lo que conviene guardar el número de intentos.

Memoria y backpressure

SimpleQueue no tiene capacidad máxima. Si los productores generan datos más rápido que los consumidores, el uso de memoria puede crecer de forma continua. Esta es su principal limitación operativa.

Usa queue.Queue(maxsize=N) cuando el volumen sea imprevisible. El límite hace que los productores esperen y crea backpressure. Si puedes procesar elementos en grupos, la guía sobre itertools.batched en Python muestra cómo reducir operaciones repetidas.

Varios consumidores

Varios hilos pueden ejecutar get() sobre la misma cola. Cada elemento será retirado por un solo consumidor. La distribución exacta depende del planificador, por lo que no debes asumir un reparto round-robin.

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

Para detenerlos, inserta un centinela por cada worker. Un único centinela solo detiene al hilo que lo recibe.

Objetos mutables

La cola transporta referencias, no copias. Si un productor modifica una lista o un diccionario después de insertarlo, el consumidor puede observar un estado inesperado. Prefiere objetos inmutables, copias o snapshots creados antes de llamar a put().

Cuándo no usar SimpleQueue

No la uses para comunicar máquinas diferentes, persistir mensajes, sobrevivir a reinicios o garantizar entrega después de una caída. Para esos requisitos utiliza un broker o stream durable como RabbitMQ, Redis Streams, Kafka o un servicio administrado.

Tampoco reemplaza a asyncio.Queue. Ejecutar un get() bloqueante en el hilo del event loop puede detener toda la aplicación asíncrona.

Pruebas

Prueba el orden FIFO, el cierre con centinelas, la producción concurrente, las excepciones y la terminación limpia. Evita depender solo de sleep(), porque produce pruebas lentas e inestables. Prefiere eventos, join() y timeouts controlados.

La guía de StrEnum en Python muestra una forma clara de representar estados cerrados de un worker, como esperando, ejecutando, fallido y detenido.

Monitorización

Como la cola no tiene límite, monitoriza la velocidad de producción, la velocidad de consumo, la latencia, los fallos de workers y la memoria. qsize() puede servir como métrica aproximada, pero no debe decidir la corrección del programa porque el valor puede cambiar inmediatamente.

Buenas prácticas

Usa un centinela único, documenta quién controla el cierre, captura errores, termina los hilos con join(), evita modificar objetos ya insertados y utiliza Queue(maxsize) cuando sea necesario controlar la memoria. Mantén explícita la política de reintentos y de elementos fallidos.

Referencias

Consulta la documentación oficial de queue.SimpleQueue y la documentación oficial de threading.

Conclusión

queue.SimpleQueue es una solución enfocada para comunicación FIFO entre hilos. Se ocupa de la sincronización y ofrece una interfaz pequeña. Funciona especialmente bien cuando no necesitas límite ni seguimiento de finalización. Su naturaleza ilimitada es el punto crítico: mide el equilibrio entre productores y consumidores y cambia a Queue(maxsize) cuando necesites backpressure.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Desarrollador trabajando con enums y código Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    StrEnum en Python: enums como strings

    Aprende StrEnum en Python para crear enums como strings, validar entradas, serializar JSON y organizar APIs y configuraciones.

    Ler mais

    Tempo de leitura: 5 minutos
    04/09/2026
    Carpetas y directorios para contextlib.chdir en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    contextlib.chdir: restaura directorios automáticamente

    Aprende contextlib.chdir en Python para cambiar directorios temporalmente, restaurar rutas y crear pruebas confiables sin errores de estado global.

    Ler mais

    Tempo de leitura: 6 minutos
    03/09/2026
    Monitoreo de rendimiento y ejecución de código Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    sys.monitoring: instrumentación de bajo overhead

    Aprende sys.monitoring en Python para instrumentar ejecución con bajo overhead, eventos selectivos, callbacks y observabilidad segura.

    Ler mais

    Tempo de leitura: 6 minutos
    03/09/2026
    Desarrollador organizando datos con operator.attrgetter en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    operator.attrgetter: ordena objetos por atributos

    Aprende operator.attrgetter en Python para ordenar, agrupar y transformar objetos por atributos simples o anidados con código claro.

    Ler mais

    Tempo de leitura: 4 minutos
    02/09/2026
    Programación asíncrona con asyncio.Runner en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    asyncio.Runner: reutiliza el event loop con seguridad

    Aprende asyncio.Runner en Python para reutilizar el event loop, controlar contexto, señales, debug, cancelación y cierre asíncrono seguro.

    Ler mais

    Tempo de leitura: 7 minutos
    02/09/2026
    Compresión de datos binarios con Zstandard en Python
    Python Avanzado
    Foto de perfil de Leandro Hirt da Academify

    compression.zstd: Zstandard con streams y diccionarios

    Aprende compression.zstd en Python para comprimir datos con Zstandard, streaming, diccionarios y límites seguros.

    Ler mais

    Tempo de leitura: 7 minutos
    01/09/2026