Referencia

Hoja de referencia

Toda la API que necesitas de un vistazo. Compila con -std=c++20 -pthread (GCC/Clang) o /std:c++20 /EHsc (MSVC).

Hilos

#include <thread>          #include <jthread>      // C++20

std::thread t(f, args);    // lanza f(args)
t.join();                  // espera y libera
t.detach();                // desenlaza (evitar)

std::jthread j(f, args);   // join automático al destruirse
j.request_stop();          // pide parada cooperativa

// dentro del hilo:
std::this_thread::sleep_for(std::chrono::milliseconds(10));
std::this_thread::yield();
std::this_thread::get_id();

// argumentos: copia; usa std::ref(x) para referencias

Mutex y candados

#include <mutex>           #include <shared_mutex>

std::mutex m;
std::lock_guard lk(m);            // toma/suelta por ámbito (RAII)
std::unique_lock lk(m);           // igual pero desbloqueable; para cv
std::scoped_lock lk(m1, m2);      // varios sin deadlock
std::shared_mutex m;              // lectores/escritor
std::shared_lock lk(m);           // lector compartido

m.lock(); m.unlock();             // a mano: evitar
m.try_lock();                     // intenta sin bloquear (bool)

Variables de condición

#include <condition_variable>

std::mutex m;
std::condition_variable cv;
bool condicion;

// productor:
{ std::lock_guard lk(m); condicion = true; }
cv.notify_one();                  // o notify_all()

// consumidor:
std::unique_lock lk(m);
cv.wait(lk, [] { return condicion; });       // SIEMPRE con predicado
cv.wait_for(lk, std::chrono::seconds(5), pred);   // timeout → false

Semáforos (C++20)

#include <semaphore>

std::counting_semaphore<10> s(10);  // contador: máx 10, inicial 10
std::binary_semaphore e(0);         // binario: inicial 0

s.acquire();            // wait / P
s.release();            // signal / V
s.try_acquire();        // bool, sin bloquear
s.try_acquire_for(d);   // bool, con límite de tiempo
s.try_acquire_until(t); // bool, hasta un instante

Atómicos

#include <atomic>

std::atomic<int> n{0};
std::atomic<bool> parar{false};

n.store(5);  n.load();  n++;  n += 1;
n.exchange(v);
n.compare_exchange_weak(exp, v);   // CAS
parar.wait(false);  parar.store(true);  parar.notify_one();  // C++20

Cola bloqueante (patrón)

template <typename T>
class ColaBloqueante {
    std::queue<T> datos;
    mutable std::mutex m;
    std::condition_variable noVacia, noLlena;
    size_t capacidad;
public:
    explicit ColaBloqueante(size_t cap) : capacidad(cap) {}

    void push(T item) {
        std::unique_lock lk(m);
        noLlena.wait(lk, [&] { return datos.size() < capacidad; });
        datos.push(std::move(item));
        noVacia.notify_one();
    }

    T pop() {
        std::unique_lock lk(m);
        noVacia.wait(lk, [&] { return !datos.empty(); });
        T item = std::move(datos.front());
        datos.pop();
        noLlena.notify_one();
        return item;
    }
};

Correspondencias clásico ↔ C++

Estilo SCTRC++ moderno
semaforo s = Nstd::counting_semaphore<N> s(N)
semaforo s = 1 (región crítica)std::mutex + candados RAII
wait(s) / signal(s)s.acquire() / s.release()
concurrente { h1(); h2(); }std::jthread t1(h1), t2(h2);
Pareja sp* / sc*ColaBloqueante o dos semáforos
while (!sensor());semáforo de evento / condición / interrupción

Compilación y verificación

# Linux / GCC
g++ -std=c++20 -Wall -Wextra -pthread planta.cpp -o planta

# Sanitizer de carreras (Linux)
g++ -std=c++20 -g -fsanitize=thread planta.cpp -o planta -pthread

# Análisis con Valgrind (helgrind)
valgrind --tool=helgrind ./planta