Fundamentos

Atómicos y sin candados

Para operaciones sencillas —un contador de piezas, una bandera de parada, un indicador de presencia— un mutex es excesivo. std::atomic ofrece operaciones indivisibles directamente soportadas por el hardware, sin bloquear a nadie.

Contadores de planta sin mutex

#include <atomic>
#include <thread>

std::atomic<int> piezasTerminadas{0};    // compartido y seguro

void hLinea(int n) {
    while (true) {
        // ... procesar una pieza ...
        piezasTerminadas++;              // fetch_add atómico: sin carreras
    }
}

int main() {
    std::thread a(hLinea, 1), b(hLinea, 2);
    // ...
    std::cout << "Total: " << piezasTerminadas.load() << "\n";
    a.join(); b.join();
}

Operaciones principales de std::atomic<T>:

OperaciónSignificado
a.load()Lectura atómica.
a.store(v)Escritura atómica.
a++ / a += nIncremento atómico (fetch_add).
a.exchange(v)Pone v y devuelve el valor anterior.
a.compare_exchange_weak(exp, v)Si vale exp, pone v; si no, carga el valor real en exp. Base de las estructuras lock-free.
a.wait(v) / a.notify_one() (C++20)Bloqueo barato hasta que el valor cambie: ideal para sensores y banderas.

Banderas de parada y sensores

std::atomic<bool> paradaEmergencia{false};

void hRobot() {
    while (!paradaEmergencia.load()) {
        // ... ciclo de trabajo ...
    }
    // salir de forma ordenada
}

// desde el hilo de seguridad:
paradaEmergencia.store(true);

Y con C++20, esperar un cambio de sensor sin sondear:

std::atomic<bool> sensorPresencia{false};

void hCinta() {
    while (true) {
        sensorPresencia.wait(false);   // duerme hasta que valga true
        // ... hay pieza en la posición ...
        sensorPresencia.wait(true);    // duerme hasta que desaparezca
    }
}

Cuándo atómico, cuándo mutex

SituaciónHerramienta
Un contador que varios hilos incrementanstd::atomic
Bandera de parada / presencia / permisostd::atomic<bool>
Dos o más variables que deben cambiar a la vez (tabla de ocupación + contador)Mutex: la atomicidad es del conjunto
Esperar a que un buffer tenga datosCola bloqueante (mutex + condiciones), no sondeo atómico
⚠ Límite de los atómicos

piezas++ atómico no basta si después usas el valor para decidir algo que otro hilo también decide: entre tu lectura y tu acción otro puede cambiarlo. Para secuencias «leer-decidir-escribir» sobre el mismo dato usa compare_exchange, o directamente un mutex.