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ón | Significado |
|---|---|
a.load() | Lectura atómica. |
a.store(v) | Escritura atómica. |
a++ / a += n | Incremento 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ón | Herramienta |
|---|---|
| Un contador que varios hilos incrementan | std::atomic |
| Bandera de parada / presencia / permiso | std::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 datos | Cola 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.