Patrones clásicos
Barrera y rendezvous
A veces los hilos no intercambian datos: solo necesitan esperarse. Una barrera es un punto donde N hilos deben presentarse todos antes de que cualquiera siga; un rendezvous es la cita entre dos. En planta aparecen en fases de proceso, lotes y arranques coordinados.
La instalación en acción
Tres tolvas se llenan a ritmos distintos, pero descargan solo cuando las tres están listas: la compuerta se abre a la vez para todas. Arranca la simulación y observa cómo las tolvas que llegan antes esperan en la barrera.
Consejo: el indicador «tolvas en la barrera» muestra cuántas esperan a la última.
Barrera simple (un solo uso)
Semaforo sLlegada(0); // señales de llegada
Semaforo sApertura(0); // permiso para continuar
std::mutex m;
int nLlegados = 0;
constexpr int N = 4; // hilos que deben encontrarse
void esperaBarrera() {
{
std::lock_guard<std::mutex> lk(m);
nLlegados++;
}
sLlegada.signal(); // «ya estoy»
if (nLlegados == N) { // el último en llegar
for (int i = 0; i < N; i++)
sApertura.signal(); // abre la barrera para todos
} else {
sApertura.wait(); // los demás esperan
}
}
Cada hilo llama a esperaBarrera(); ninguno pasa hasta que hayan llegado los N. Ejemplo: cuatro
dosificadores que deben descargar sus ingredientes a la vez en la mezcladora.
Barrera reutilizable (por fases)
Si el proceso tiene fases (llenado → calentado → mezclado) y los hilos deben sincronizarse al final de
cada fase, la barrera debe «rearmarse». std::barrier de C++20 lo da hecho:
#include <barrier>
std::barrier finDeFase(4); // 4 hilos participantes
void hEstacion() {
while (true) {
trabajarEnLaFase();
finDeFase.arrive_and_wait(); // espera a los demás y rearma
}
}
Rendezvous entre dos hilos
Es la barrera de dos, pero con semáforos queda más transparente y permite que cada hilo anuncie su llegada y espere la del otro:
Semaforo sLlegadaA(0), sLlegadaB(0);
void hA() { punto1(); sLlegadaA.signal(); sLlegadaB.wait(); punto2(); }
void hB() { punto1(); sLlegadaB.signal(); sLlegadaA.wait(); punto2(); }
Aplicación: el robot y la prensa deben terminar sus movimientos antes de abrir la guarda de seguridad.
El grupo exacto: «entran de tres en tres»
Variante del cuaderno (ej60): una máquina de mantenimiento solo opera sobre grupos de 3 robots del mismo modelo. Se combina un semáforo contador que deja pasar de tres en tres con un mecanismo de aviso al tercero:
Semaforo sGrupo(3); // solo pasan 3
Semaforo sEntra(0); // aviso del tercero a los otros dos
std::mutex mtx;
int nPreparados = 0;
void esperaGrupo() {
sGrupo.wait(); // tercer wait deja el semáforo en 0
{
std::lock_guard<std::mutex> lk(mtx);
nPreparados++;
if (nPreparados == 3) {
sEntra.signal(); // el tercero abre
sEntra.signal();
}
}
if (nPreparados < 3) sEntra.wait(); // los dos primeros esperan
}
¿N hilos se esperan una vez? Barrera simple. ¿Se esperan en cada fase? std::barrier. ¿Dos
hilos se citan? Rendezvous con dos semáforos. ¿Entran en grupos de K? Semáforo contador K + aviso del
último.