Este artículo explica std::shared_mutex, una herramienta valiosa introducida en C++17 que optimiza el acceso concurrente a datos compartidos, especialmente en escenarios de lectura intensiva. Comienza con un ejemplo básico: un contador que se incrementa y se lee por múltiples hilos, utilizando std::mutex. Si bien esta implementación es correcta y segura, presenta una limitación importante: el acceso exclusivo. Esto significa que incluso las operaciones de lectura (get) bloquean a otras, incluso si no modifican el estado del contador, lo que reduce la escalabilidad y el paralelismo.
El problema se agudiza cuando los datos compartidos se leen con mucha más frecuencia de lo que se modifican, como en casos de configuración, cachés, tablas de búsqueda, estadísticas o métricas. El ejemplo proporcionado ilustra cómo, con std::mutex, los lectores se ven bloqueados incluso cuando no hay escrituras, generando un cuello de botella.
std::shared_mutex resuelve este problema al permitir dos modos de bloqueo: propiedad compartida (múltiples hilos pueden mantener el bloqueo simultáneamente para lecturas) y propiedad exclusiva (solo un hilo puede mantener el bloqueo para escrituras). Esto es ideal para estructuras de datos predominantemente de lectura. El contador de ejemplo se refactoriza para usar std::shared_lock para las lecturas y std::unique_lock para las escrituras, permitiendo que múltiples lectores accedan al contador simultáneamente. Aunque la salida observable (los valores leídos) puede parecer similar con ambos tipos de mutex, la diferencia clave es la capacidad de std::shared_mutex para permitir la concurrencia de lectores.
Un ejemplo de medición de rendimiento demuestra la mejora. Simulando un trabajo de lectura y escritura con tiempos de espera, se observa una reducción significativa en el tiempo total de ejecución al usar std::shared_mutex. En el ejemplo proporcionado, con 2 hilos de hardware, el uso de std::mutex tardó 285ms, mientras que std::shared_mutex tardó solo 102ms. Es importante tener en cuenta que la mejora es más notable cuando la sección de lectura protegida es compleja y hay una alta contención. En resumen, std::shared_mutex es una herramienta práctica y valiosa para mejorar la concurrencia en C++17, especialmente en escenarios de lectura intensiva, y sigue siendo relevante incluso en versiones más recientes del lenguaje.
