Espacios de nombres
Variantes
Acciones

std::shared_mutex

De cppreference.com
< cpp‎ | thread
 
 
Biblioteca de apoyo de concurrencia
Hilos
(C++11)
(C++20)
Espacio de nombres this_thread
(C++11)
(C++11)
(C++11)
Cancelación cooperativa
Exclusión mutua
(C++11)
shared_mutex
(C++17)
Gestión genérica de bloqueo
(C++11)
(C++11)
(C++11)
(C++11)
Variables de condición
(C++11)
Semáforos
Pestillos y barreras
(C++20)
(C++20)
Futuros
(C++11)
(C++11)
(C++11)
Recuperación segura
Punteros de riesgo
Tipos atómicos
(C++11)
(C++20)
Inicialización de tipos atómicos
(C++11)(en desuso en C++20)
(C++11)(en desuso en C++20)
Orden de memoria
Funciones independientes para operaciones atómicas
Funciones independientes para indicadores atómicos
 
 
Definido en el archivo de encabezado <shared_mutex>
class shared_mutex;
(desde C++17)

La clase shared_mutex es una primitiva de sincronización que se puede utilizar para proteger datos compartidos de un acceso simultáneo por varios hilos/subprocesos. A diferencia de otros tipos mutex que facilitan el acceso exclusivo, un shared_mutex tiene dos niveles o modalidades de acceso:

  • compartido - varios hilos pueden tomar posesión del mismo mutex.
  • exclusivo - solo un hilo puede poseer el mutex.

Si un hilo ha adquirido el bloqueo exclusivo (a través de lock o try_lock), ningún otro hilo puede adquirir el bloqueo (incluido el compartido).

Si un hilo ha adquirido el bloqueo compartido a través de lock_shared o try_lock_shared), ningún otro hilo puede adquirir el bloqueo (incluido el bloqueo exclusivo, pero puede adquirir el bloqueo compartido.

Solo cuando el bloqueo exclusivo no ha sido adquirido por ningún hilo, el bloqueo compartido puede adquirirse por múltiples hilos.

Dentro de un hilo, solo se puede adquirir un bloqueo (compartido o exclusivo) a la vez.

Los mutexes compartidos son especialmente útiles cuando los datos compartidos pueden leerse 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 requerimientos de SharedMutex y StandardLayoutType.

Contenido

[editar]Tipos miembro

Tipo miembro Definición
native_handle_type(no siempre está presente)definido por la implementación[editar]

[editar]Funciones miembro

Construye el mutex
(función miembro pública)[editar]
Destruye el mutex
(función miembro pública)[editar]
operator=
[eliminada]
No es asignable mediante copia
(función miembro pública)[editar]
Bloqueo exclusivo
Bloquea el mutex; se bloquea si el mutex no está disponible
(función miembro pública)[editar]
Intenta bloquear el mutex; regresa si el mutex no está disponible
(función miembro pública)[editar]
Desbloquea el mutex
(función miembro pública)[editar]
Bloqueo compartido
Bloquea el mutex para propiedad compartida; se bloquea si el mutex no está disponible
(función miembro pública)[editar]
Intenta bloquear el mutex para propiedad compartida; regresa si el mutex no está disponible
(función miembro pública)[editar]
Desbloquea el mutex (propiedad compartida)
(función miembro pública)[editar]
Identificador nativo
Devuelve el identificador nativo subyacente definido por la implementación
(función miembro pública)[editar]

[editar]Ejemplo

#include <iostream>#include <mutex>#include <shared_mutex>#include <thread>   class ThreadSafeCounter {public: ThreadSafeCounter()=default;   // Múltiples hilos/lectores pueden leer el valor del contador al mismo tiempo.unsignedint get()const{std::shared_lock lock(mutex_);return value_;}   // Solo un hilo/escritor puede incrementar/escribir el valor del contador.unsignedint increment(){std::unique_lock lock(mutex_);return++value_;}   // Solo un hilo/escritor puede restablecer/escribir el valor del contador.void reset(){std::unique_lock lock(mutex_); value_ =0;}   private: mutable std::shared_mutex mutex_;unsignedint value_ =0;};   int main(){ ThreadSafeCounter counter;   auto increment_and_print =[&counter](){for(int i =0; i <3; i++){std::cout<<std::this_thread::get_id()<<' '<< counter.increment()<<'\n';   // Nota: Escribir a std::cout de hecho también necesita sincronizarse// por otro std::mutex. Se ha omitido para hacer corto el ejemplo.}};   std::thread thread1(increment_and_print);std::thread thread2(increment_and_print);   thread1.join(); thread2.join();}   // Explicación: El resultado a continuación se generó en una máquina de un solo// núcleo. Cuando thread1 comienza, ingresa al bucle por primera vez y llama a// increment() seguido de get(). Sin embargo, antes de que pueda imprimir el// valor devuelto a std::cout, el programador pone a thread1 en suspensión y// despierta a thread2, que obviamente, tiene tiempo suficiente para ejecutar// las tres iteraciones del bucle a la vez. De regreso a thread1, aún en la// primera iteración del ciclo, finalmente imprime su copia local del valor del// contador, que es 1, a std::cout y luego ejecuta las dos iteraciones restantes// del bucle. En una máquina de varios núcleos, ninguno de los hilos se coloca en// modo de suspensión y es más probable que la salida esté en orden ascendente.

Posible salida:

123084176803584 2 123084176803584 3 123084176803584 4 123084185655040 1 123084185655040 5 123084185655040 6

[editar]Véase también

Proporciona un servicio de exclusión mutua compartida e implementa bloqueo con un tiempo de espera.
(clase)[editar]
Implementa un envoltorio de propiedad de un mutex movible.
(plantilla de clase)[editar]
Implementa un envoltorio de propiedad de mutex movible.
(plantilla de clase)[editar]
close