C ++ 17 introdujo una nueva clase de bloqueo llamada std::scoped_lock
.
A juzgar por la documentación, se parece a la std::lock_guard
clase ya existente .
¿Cuál es la diferencia y cuándo debo usarla?
c++
multithreading
locking
c++17
Stephan Dollberg
fuente
fuente
lock_guard
. Pero ciertamente hace que las clases de guardia sean un poco más fáciles de usar.La única e importante diferencia es que
std::scoped_lock
tiene un constructor variable que toma más de un mutex. Esto permite bloquear múltiples mutexes en un punto muerto evitando la forma como sistd::lock
se usaran.Anteriormente, tenía que bailar un poco para bloquear múltiples mutexes de manera segura utilizando
std::lock
como se explica esta respuesta .La adición del bloqueo de alcance hace que sea más fácil de usar y evita los errores relacionados. Puede considerar en
std::lock_guard
desuso. El caso de argumento único destd::scoped_lock
puede implementarse como una especialización y no tendrá que temer sobre posibles problemas de rendimiento.GCC 7 ya tiene soporte para lo
std::scoped_lock
que se puede ver aquí .Para obtener más información, puede leer el documento estándar.
fuente
scoped_lock lk; // locks all mutexes in scope
. LGTM.scoped_lock lk;
es la nueva taquigrafía parascoped_lock<> lk;
. No hay ninguna mutex. Entonces tienes razón. ;-)Respuesta tardía, y principalmente en respuesta a:
Para el caso común de que uno necesita bloquear exactamente un mutex,
std::lock_guard
tiene una API que es un poco más segura de usar quescoped_lock
.Por ejemplo:
Es probable que el fragmento anterior sea un error accidental en tiempo de ejecución porque se compila y luego no hace absolutamente nada. El codificador probablemente quiso decir:
Ahora se bloquea / desbloquea
mut
.Si
lock_guard
se utilizó en los dos ejemplos anteriores, el primer ejemplo es un error en tiempo de compilación en lugar de un error en tiempo de ejecución, y el segundo ejemplo tiene una funcionalidad idéntica a la versión que utilizascoped_lock
.Entonces, mi consejo es usar la herramienta más simple para el trabajo:
lock_guard
si necesita bloquear exactamente 1 mutex para un alcance completo.scoped_lock
si necesita bloquear una cantidad de mutexes que no es exactamente 1.unique_lock
si necesita desbloquear dentro del alcance del bloque (que incluye el uso con acondition_variable
).Este consejo no no implica que
scoped_lock
debe ser rediseñado para que no acepte 0 mutex. Existen casos de uso válidos en los que es deseablescoped_lock
aceptar paquetes de parámetros de plantilla variadic que pueden estar vacíos. Y la caja vacía no debe bloquear nada.Y es por eso
lock_guard
que no está en desuso.scoped_lock
yunique_lock
puede ser un superconjunto de funcionalidades delock_guard
, pero ese hecho es una espada de doble filo. A veces es igual de importante lo que un tipo no hará (construcción predeterminada en este caso).fuente
Aquí hay una muestra y una cita de C ++ Concurrency in Action :
vs.
fuente