std:: shared_mutex
|
Definido en el encabezado
<shared_mutex>
|
||
|
class
shared_mutex
;
|
(desde C++17) | |
La clase
shared_mutex
es un primitivo de sincronización que puede utilizarse para proteger datos compartidos de ser accedidos simultáneamente por múltiples hilos. A diferencia de otros tipos de mutex que facilitan acceso exclusivo, un shared_mutex tiene dos niveles de acceso:
- shared - varios hilos pueden compartir la propiedad del mismo mutex.
- exclusive - solo un hilo puede poseer el mutex.
Si un hilo ha adquirido el bloqueo exclusivo (a través de lock , try_lock ), ningún otro hilo puede adquirir el bloqueo (incluyendo el compartido ).
Si un hilo ha adquirido el bloqueo compartido (a través de lock_shared , try_lock_shared ), ningún otro hilo puede adquirir el bloqueo exclusivo , pero sí puede adquirir el bloqueo compartido .
Solo cuando el exclusive lock no ha sido adquirido por ningún thread, el shared lock puede ser adquirido por múltiples threads.
Dentro de un hilo, solo se puede adquirir un bloqueo ( shared o exclusive ) al mismo tiempo.
Los mutex compartidos son especialmente útiles cuando los datos compartidos pueden ser leídos de forma segura por cualquier número de hilos simultáneamente, pero un hilo solo puede escribir los mismos datos cuando ningún otro hilo está leyendo o escribiendo al mismo tiempo.
La clase
shared_mutex
satisface todos los requisitos de
SharedMutex
y
StandardLayoutType
.
Contenidos |
Tipos de miembros
| Tipo de miembro | Definición |
native_handle_type
(
opcional*
)
|
definido por la implementación |
Funciones miembro
|
construye el mutex
(función miembro pública) |
|
|
destruye el mutex
(función miembro pública) |
|
|
operator=
[deleted]
|
no asignable por copia
(función miembro pública) |
Bloqueo exclusivo |
|
|
bloquea el mutex, se bloquea si el mutex no está disponible
(función miembro pública) |
|
|
intenta bloquear el mutex, retorna si el mutex no está disponible
(función miembro pública) |
|
|
desbloquea el mutex
(función miembro pública) |
|
|
|
|
|
bloquea el mutex para propiedad compartida, se bloquea si el mutex no está disponible
(función miembro pública) |
|
|
intenta bloquear el mutex para propiedad compartida, retorna si el mutex no está disponible
(función miembro pública) |
|
|
desbloquea el mutex (propiedad compartida)
(función miembro pública) |
|
Manejador nativo |
|
|
retorna el objeto de manejador nativo definido por la implementación subyacente
(función miembro pública) |
|
Ejemplo
La salida a continuación fue generada en una máquina de un solo núcleo. Cuando
thread1
comienza, entra al bucle por primera vez y llama a
increment()
seguido de
get()
. Sin embargo, antes de que pueda imprimir el valor devuelto en
std::
cout
, el planificador pone a
thread1
en suspensión y despierta a
thread2
, que obviamente tiene tiempo suficiente para ejecutar las tres iteraciones del bucle de una vez. De vuelta en
thread1
, todavía en la primera iteración del bucle, finalmente imprime su copia local del valor del contador, que es
1
, en
std::cout
y luego ejecuta las dos iteraciones restantes del bucle. En una máquina multi-núcleo, ninguno de los hilos se pone en suspensión y es más probable que la salida esté en orden ascendente.
#include <iostream> #include <mutex> #include <shared_mutex> #include <syncstream> #include <thread> class ThreadSafeCounter { public: ThreadSafeCounter() = default; // Multiple threads/readers can read the counter's value at the same time. unsigned int get() const { std::shared_lock lock(mutex_); return value_; } // Only one thread/writer can increment/write the counter's value. void increment() { std::unique_lock lock(mutex_); ++value_; } // Only one thread/writer can reset/write the counter's value. void reset() { std::unique_lock lock(mutex_); value_ = 0; } private: mutable std::shared_mutex mutex_; unsigned int value_{}; }; int main() { ThreadSafeCounter counter; auto increment_and_print = [&counter]() { for (int i{}; i != 3; ++i) { counter.increment(); std::osyncstream(std::cout) << std::this_thread::get_id() << ' ' << counter.get() << '\n'; } }; std::thread thread1(increment_and_print); std::thread thread2(increment_and_print); thread1.join(); thread2.join(); }
Salida posible:
123084176803584 2 123084176803584 3 123084176803584 4 123084185655040 1 123084185655040 5 123084185655040 6
Véase también
|
(C++14)
|
proporciona funcionalidad de exclusión mutua compartida e implementa bloqueo con tiempo de espera
(clase) |
|
(C++14)
|
implementa un envoltorio de propiedad de mutex compartido movible
(plantilla de clase) |
|
(C++11)
|
implementa un envoltorio de propiedad de mutex movible
(plantilla de clase) |