Concurrencia y Multihilo en C++: Nivel Avanzado

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Concurrencia y Multihilo en C++: Nivel Avanzado

\n\n

Las aplicaciones modernas requieren el máximo rendimiento, y el multihilo en C++ es una de las herramientas clave para lograrlo. Sin embargo, los mecanismos básicos (std::thread, std::mutex) a menudo generan bloqueos, condiciones de carrera y reducción de la eficiencia. En este artículo, exploraremos técnicas avanzadas para trabajar con concurrencia en C++: desde operaciones atómicas hasta estructuras de datos lock-free y tareas asíncronas.

\n\n

1. Operaciones Atómicas y Ordenamiento de Memoria

\n\n

Los mutex clásicos son un mecanismo pesado. Para contadores simples o banderas, es mejor usar std::atomic. Garantiza la atomicidad de lectura/escritura sin bloqueos. Sin embargo, a nivel avanzado es importante entender el memory ordering (ordenamiento de memoria): el modelo de memoria de C++ que define la visibilidad de los cambios entre hilos.

\n\n

Órdenes de memoria principales:

\n
    \n
  • memory_order_relaxed — garantías mínimas, solo atomicidad.
  • \n
  • memory_order_consume — se usa raramente, depende de los datos.
  • \n
  • memory_order_acquire — todas las lecturas/escrituras posteriores no pueden reordenarse antes de esta operación.
  • \n
  • memory_order_release — todas las escrituras anteriores se vuelven visibles para otros hilos después de esta operación.
  • \n
  • memory_order_acq_rel — combinación de acquire y release.
  • \n
  • memory_order_seq_cst — el más estricto, consistencia secuencial global (por defecto).
  • \n
\n\n

Ejemplo de uso:

\n
#include <atomic>\n#include <thread>\n#include <cassert>\n\nstd::atomic<bool> ready{false};\nint data = 0;\n\nvoid producer() {\n    data = 42;                                   // escritura de datos\n    ready.store(true, std::memory_order_release); // publicamos la bandera\n}\n\nvoid consumer() {\n    while (!ready.load(std::memory_order_acquire)) // esperamos la bandera\n        ;\n    assert(data == 42); // garantizado que veremos data == 42\n}\n\nint main() {\n    std::thread t1(producer);\n    std::thread t2(consumer);\n    t1.join();\n    t2.join();\n    return 0;\n}
\n\n

Aquí, release y acquire garantizan que la escritura de data ocurra antes de establecer la bandera, y la lectura después. Esto es más rápido que un mutex.

\n\n

2. Estructuras de Datos Lock-Free

\n\n

Los algoritmos lock-free evitan bloqueos utilizando operaciones atómicas y CAS (Compare-And-Swap). Un ejemplo clásico es una pila lock-free basada en una lista enlazada simple.

\n\n

Implementación de una pila lock-free:

\n
#include <atomic>\n#include <memory>\n\ntemplate<typename T>\nclass LockFreeStack {\nprivate:\n    struct Node {\n        T data;\n        Node* next;\n        Node(const T& val) : data(val), next(nullptr) {}\n    };\n    std::atomic<Node*> head{nullptr};\n\npublic:\n    void push(const T& val) {\n        Node* new_node = new Node(val);\n        new_node->next = head.load(std::memory_order_relaxed);\n        while (!head.compare_exchange_weak(\n            new_node->next, new_node,\n            std::memory_order_release,\n            std::memory_order_relaxed)) {\n            // bucle hasta que CAS tenga éxito\n        }\n    }\n\n    bool pop(T& result) {\n        Node* old_head = head.load(std::memory_order_relaxed);\n        while (old_head != nullptr &&\n               !head.compare_exchange_weak(\n                   old_head, old_head->next,\n                   std::memory_order_acquire,\n                   std::memory_order_relaxed)) {\n            // esperamos\n        }\n        if (old_head == nullptr) return false;\n        result = old_head->data;\n        // Atención: en código real se necesita un recolector de basura o hazard pointers\n        delete old_head;\n        return true;\n    }\n};
\n\n

Notas importantes:

\n
    \n

Blogs

Book Recommendations