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 SCTR | C++ moderno |
|---|---|
semaforo s = N | std::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