¿Cómo se puede sincronizar la interacción entre hilos?
sobes.tech AI
Respuesta de la IA
Existen varios mecanismos principales de sincronización de hilos en C++:
-
Mutexes: Garantizan exclusión mutua. Solo un hilo puede poseer un mutex en un momento dado. Se utilizan para proteger recursos compartidos contra accesos simultáneos.
#include <mutex> std::mutex myMutex; void criticalSection() { std::lock_guard<std::mutex> lock(myMutex); // Adquisición del mutex // Trabajo con recurso compartido } // El mutex se libera automáticamente al salir del ámbito -
Semáforos: Controlan el acceso a recursos limitados. Tienen un contador que indica la cantidad de recursos disponibles. Los hilos pueden disminuir (para obtener un recurso) o aumentar (para liberar).
#include <semaphore.h> // Generalmente en sistemas POSIX sem_t mySemaphore; void initSemaphore(int count) { sem_init(&mySemaphore, 0, count); // Inicialización del semáforo con contador count } void acquireResource() { sem_wait(&mySemaphore); // Decrementa el contador, bloquea si es 0 // Uso del recurso } void releaseResource() { sem_post(&mySemaphore); // Incrementa el contador } -
Variables de condición: Permiten que los hilos esperen a que se cumpla una condición. Generalmente se usan junto con mutexes. Un hilo que espera libera el mutex y se bloquea hasta que otro hilo le notifique que la condición se cumple.
#include <condition_variable> #include <mutex> #include <queue> std::condition_variable myCondition; std::mutex myMutex; std::queue<int> myQueue; void producer(int value) { std::lock_guard<std::mutex> lock(myMutex); myQueue.push(value); myCondition.notify_one(); // Notifica a un hilo en espera } int consumer() { std::unique_lock<std::mutex> lock(myMutex); myCondition.wait(lock, [&]{ return !myQueue.empty(); }); // Espera a la condición int value = myQueue.front(); myQueue.pop(); return value; } -
Variables atómicas: Permiten realizar operaciones simples (lectura, escritura, modificación) de forma atómica, sin necesidad de mutexes para esas operaciones específicas.
#include <atomic> std::atomic_int atomicCounter(0); void incrementCounter() { atomicCounter++; // Incremento atómico } -
Barrera: Sincronizan varios hilos para que ninguno pueda continuar hasta que todos hayan llegado a la barrera.
#include <barrier> // C++20 std::barrier myBarrier(3); // Barrera para 3 hilos void workerThread() { // Realización de parte del trabajo myBarrier.arrive_and_wait(); // Espera a que todos lleguen a la barrera // Realización de la siguiente parte del trabajo }
La elección de un mecanismo específico depende de la naturaleza de la interacción entre los hilos:
- Mutexes: La forma más común de proteger datos compartidos.
- Semáforos: Gestión del acceso a recursos limitados.
- Variables de condición: Espera a que ocurra un evento o estado específico.
- Variables atómicas: Ejecución eficiente de operaciones simples y atómicas.
- Barrera: Sincronización de hilos para avanzar conjuntamente a la siguiente etapa.