Saltar al contenido

Diferencias entre variables condicionales, mutex y bloqueos

Recuerda que en la informática cualquier problema puede tener diferentes resoluciones, por lo tanto nosotros enseñaremos lo mejor y más eficiente.

Solución:

En la página a la que se refiere, “mutex” es la primitiva de sincronización de bajo nivel real. Puede tomar un mutex y luego liberarlo, y solo un hilo puede tomarlo a la vez (por lo tanto, es una primitiva de sincronización). Un mutex recursivo es uno que puede ser tomado por el mismo subproceso varias veces, y luego debe ser liberado tantas veces por el mismo subproceso antes de que otros puedan tomarlo.

Un “bloqueo” aquí es solo una clase contenedora de C ++ que toma un mutex en su constructor y lo libera en el destructor. Es útil para establecer la sincronización para ámbitos de C ++.

Una variable de condición es una forma más avanzada / de alto nivel de sincronización primitiva que combina un bloqueo con un mecanismo de “señalización”. Se utiliza cuando los subprocesos necesitan esperar a que un recurso esté disponible. Un hilo puede “esperar” en un CV y ​​luego el productor de recursos puede “señalar” la variable, en cuyo caso los hilos que esperan el CV son notificados y pueden continuar la ejecución. Un mutex se combina con CV para evitar la condición de carrera en la que un hilo comienza a esperar en un CV al mismo tiempo que otro hilo quiere señalarlo; entonces no es controlable si la señal se entrega o se pierde.

No estoy muy familiarizado con C ++ 0x, así que tome esta respuesta con un grano de sal.

re: Mutex vs. bloqueos: De la documentación que publicaste, parece un mutex es un objeto que representa un mutex del sistema operativo, mientras que un lock es un objeto que tiene un mutex para facilitar el patrón RAII.

Las variables de condición son un mecanismo útil para asociar un mecanismo de bloqueo / señalización (señal + espera) con un mecanismo de exclusión mutua, pero mantenerlos desacoplados en el sistema operativo para que usted, como programador del sistema, pueda elegir la asociación entre condvar y mutex. (útil para tratar con múltiples conjuntos de objetos a los que se accede simultáneamente) Rob Krten tiene algunas buenas explicaciones sobre condvars en uno de los capítulos en línea de su libro sobre QNX.

En cuanto a las referencias generales: este libro (aún no publicado) parece interesante.

Esta pregunta ha sido respondida. Solo agrego esto que puede ayudar a decidir CUÁNDO usar estas primitivas de sincronización.

Simplemente, el mutex se utiliza para garantizar el acceso mutuo a un recurso compartido en la sección crítica de varios subprocesos. La suerte es un término general, pero un mutex binario se puede utilizar como bloqueo. En C ++ moderno usamos lock_guard y objetos similares para utilizar RAII para simplificar y hacer seguro el uso de mutex. La variable condicional es otra primitiva que a menudo se combina con un mutex para hacer que algo se conozca como monitor.

Estoy teniendo dificultades para averiguar cuándo usar cuál de estas cosas (cv, mutex y bloqueo). ¿Alguien puede explicar o señalar un recurso?

Utilice un mutex para garantizar el acceso exclusivo mutuo a algo. Es la solución predeterminada para una amplia gama de problemas de simultaneidad. Use lock_guard si tiene un alcance en C ++ que desea proteger con un mutex. El mutex es manejado por lock_guard. Simplemente crea un lock_guard en el alcance y lo inicializa con un mutex y luego C ++ hace el resto por usted. El mutex se libera cuando el alcance se elimina de la pila, por cualquier motivo, incluido el lanzamiento de una excepción o el regreso de una función. Es la idea detrás de RAII y lock_guard es otro controlador de recursos.

Hay algunos problemas de simultaneidad que no se pueden resolver fácilmente con solo usar un mutex o una solución simple puede generar complejidad o ineficiencia. Por ejemplo, el problema del consumidor producido es uno de ellos. Si queremos implementar un hilo consumidor leyendo elementos de un búfer compartido con un productor, deberíamos proteger el búfer con un mutex pero, sin usar una variable condicional, deberíamos bloquear el mutex, verificar el búfer y leer un artículo si no está vacío , desbloquéelo y espere un período de tiempo, vuelva a bloquearlo y continúe. Es una pérdida de tiempo si el búfer a menudo está vacío (ocupado esperando) y también habrá muchos bloqueos y desbloqueo y suspensiones.

La solución que necesitamos para el problema productor-consumidor debe ser más simple y más eficiente. Un monitor (un mutex + una variable condicional) nos ayuda aquí. Todavía necesitamos un mutex para garantizar el acceso exclusivo mutuo, pero una variable condicional nos permite dormir y esperar una determinada condición. La condición aquí es que el productor agregue un artículo al búfer. El hilo del productor notifica al hilo del consumidor que hay un artículo en el búfer y el consumidor se despierta y obtiene el artículo. Simplemente, el productor bloquea el mutex, pone algo en el búfer y notifica al consumidor. El consumidor bloquea el mutex, duerme mientras espera una condición, se despierta cuando hay algo en el búfer y obtiene el elemento del búfer. Es una solución más sencilla y eficaz.

La próxima vez que se enfrente a un problema de concurrencia, piense de esta manera: si necesita acceso exclusivo mutuo a algo, use un mutex. Utilice lock_guard si desea ser más seguro y sencillo. Si el problema tiene una pista de esperar una condición que debe ocurrir en otro hilo, PODRÍA necesitar una variable condicional.

Como regla general, primero analice su problema e intente encontrar un problema de concurrencia famoso similar al suyo (por ejemplo, vea la sección de problemas clásicos de sincronización en esta página). Lea acerca de las soluciones propuestas para la solución conocida para alcanzar la mejor. Es posible que necesite alguna personalización.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *