0Pricing
C++ Academy · Lección

Implementación de una cola sin bloqueos

Recorra el diseño de una cola sin bloqueos para un productor y un consumidor.

Implementación de una cola sin bloqueos es una lección gratuita de C++ Academy en CoddyKit. Esta es la lección 3 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de C++ Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de C++ Academy incluye 4 lecciones en total.

¿Por qué utilizar colas lock-free?

Las colas con mutexes pueden convertirse en cuellos de botella bajo una alta contención. Una cola lock-free permite que los productores y consumidores progresen de forma concurrente.

SPSC frente a MPMC

Dos variantes:

  • SPSC — un único productor y un único consumidor (la más sencilla y rápida)
  • MPMC — varios productores y varios consumidores (la más general)

SPSC es la opción natural cuando controla ambos extremos.

Esquema de búfer circular SPSC

Un búfer circular con dos índices: head (consumidor) y tail (productor). Cada lado actualiza su propio índice.

template <typename T, size_t N>
class SpscQueue {
    T buffer_[N];
    std::atomic<size_t> head_{0};
    std::atomic<size_t> tail_{0};
public:
    bool push(const T& v);
    bool pop(T& v);
};

Inserción SPSC

El productor comprueba los espacios libres, escribe y después publica la operación actualizando tail.

bool push(const T& v) {
    const size_t t = tail_.load(std::memory_order_relaxed);
    const size_t next = (t + 1) % N;
    if (next == head_.load(std::memory_order_acquire))
        return false;     // full
    buffer_[t] = v;
    tail_.store(next, std::memory_order_release);
    return true;
}

Extracción SPSC

El consumidor comprueba si hay datos, los lee y después publica la operación actualizando head.

bool pop(T& v) {
    const size_t h = head_.load(std::memory_order_relaxed);
    if (h == tail_.load(std::memory_order_acquire))
        return false;     // empty
    v = buffer_[h];
    head_.store((h + 1) % N, std::memory_order_release);
    return true;
}

Correspondencia del ordenamiento de memoria

El almacenamiento release en tail se sincroniza con la carga acquire de tail en el consumidor, y viceversa. Sin el ordenamiento adecuado, las escrituras de datos podrían reordenarse después de la actualización del índice.

Relleno de líneas de caché

Para evitar la compartición falsa, coloque head_ y tail_ en líneas de caché separadas (normalmente a 64 bytes de distancia). Utilice alignas.

alignas(64) std::atomic<size_t> head_{0};
alignas(64) std::atomic<size_t> tail_{0};

MPMC: mucho más difícil

Varios productores o consumidores requieren coordinación adicional, normalmente mediante bucles CAS sobre índices compartidos. Existen muchos diseños (cola de Vyukov, MS-queue y diseños basados en Hazard Pointers).

Boost.Lockfree

Las colas sin bloqueos listas para producción son difíciles de implementar. Utilice Boost.Lockfree o ProducerConsumerQueue de Folly en lugar de crear su propia implementación.

Compromisos

Colas sin bloqueos:

  • Mayor rendimiento bajo contención
  • Latencia acotada (no hay que esperar a que se libere un bloqueo)
  • Mucho más difíciles de escribir y depurar
  • Los errores de ordenamiento de memoria son silenciosos y difíciles de detectar

Pruebas de código sin bloqueos

Utilice ThreadSanitizer (-fsanitize=thread) para detectar condiciones de carrera. Use pruebas de estrés con inserciones aleatorias de pausas para revelar errores de ordenamiento.

Cuándo basta con un mutex

La mayoría de las aplicaciones no necesitan colas sin bloqueos. Mida primero: una cola protegida por un mutex bien implementado suele ofrecer un rendimiento adecuado, especialmente con procesamiento por lotes.

Comprobación rápida

¿Qué es la compartición falsa y por qué se añaden datos de relleno a head_ y tail_?

Resumen

Una cola SPSC sin bloqueos utiliza un búfer circular con tail, propiedad del productor, y head, propiedad del consumidor. Utilice ordenamiento acquire/release y añada datos de relleno para colocar los índices en líneas de caché separadas. Para MPMC, prefiera una biblioteca probada.

Preguntas frecuentes

¿La lección «Implementación de una cola sin bloqueos» es gratis?

Sí — el texto completo de «Implementación de una cola sin bloqueos» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de C++ Academy, actualiza a CoddyKit PRO. El curso de C++ Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Implementación de una cola sin bloqueos»?

Recorra el diseño de una cola sin bloqueos para un productor y un consumidor. Practicas C++ Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar C++ Academy?

No se requiere experiencia previa. C++ Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 3 de 4.

¿Cuánto tiempo toma la lección «Implementación de una cola sin bloqueos»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de C++ Academy?

Sí. Cada lección de C++ Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. std::atomic y órdenes de memoria
  2. Patrones de comparación e intercambio (CAS)
  3. Implementación de una cola sin bloqueos
  4. Punteros de peligro y el problema ABA
← Volver a C++ Academy