2010-10-20 17 views
16

He estado leyendo sobre acceso multihilo y recursos compartidos y uno de los muchos (para mí) nuevos conceptos es el bloqueo mutex. Lo que parece que no puedo averiguar es qué está sucediendo realmente con el hilo que encuentra que una "sección crítica" está bloqueada. Dice en muchos lugares que el hilo se "bloquea", pero ¿qué significa eso? ¿Está suspendido y se reanudará cuando se levante el bloqueo? ¿O lo intentará de nuevo en la próxima iteración del "ciclo de ejecución"?Bloqueo Mutex: ¿qué significa "bloqueo"?

La razón por la que pregunto es porque quiero que los eventos proporcionados por el sistema (mouse, teclado, etc.), que (al parecer) se entregan en el hilo principal, se manejen en una parte muy específica del ciclo de ejecución de mi hilo secundario Entonces, sea cual sea el evento entregado, hago cola en mi propia estructura de datos. Obviamente, la estructura de datos necesita un bloqueo mutex porque está siendo modificado por ambos hilos. La pieza de rompecabezas que falta es: ¿qué sucede cuando un evento se entrega en una función en el hilo principal, quiero ponerlo en cola, pero la cola está bloqueada? ¿Se suspenderá el hilo principal o saltará por encima de la sección bloqueada y saldrá del alcance (perdiendo el evento)?

Respuesta

11

Bloqueado significa que la ejecución se atasca allí; en general, el hilo pone el hilo a dormir y cede el procesador a otro hilo. Cuando un hilo está bloqueado tratando de adquirir un mutex, la ejecución se reanuda cuando se lanza el mutex, aunque el hilo puede bloquearse nuevamente si otro hilo agarra el mutex antes de que pueda.

Generalmente, hay una operación de bloqueo de prueba que agarra el mutex si es posible, y si no, devolverá un error. Pero eventualmente tendrá que mover el evento actual a esa cola. Además, si demora mover los eventos a la secuencia donde se manejan, la aplicación dejará de responder independientemente.

Una cola es en realidad un caso en el que puede salirse con la suya sin utilizar un mutex. Por ejemplo, Mac OS X (y posiblemente también iOS) proporciona las funciones OSAtomicEnqueue() y OSAtomicDequeue() (ver man atomic o <libkern/OSAtomic.h>) que aprovechan las operaciones atómicas específicas del procesador para evitar el uso de un bloqueo.

Pero, ¿por qué no simplemente procesa los eventos en el hilo principal como parte del ciclo de ejecución principal?

+0

El ciclo de ejecución principal no es lo que impulsa la aplicación. Estoy en Mac OSX y uso un CVDisplayLink que efectivamente está generando un hilo separado (alta prioridad) que a su vez impulsará mi ciclo de ejecución. Los eventos, tal como lo entiendo, se entregarán en el hilo principal, por lo que la sincronización parece estar en orden. – zmippie

1

El bloqueo significa exactamente eso. Esta bloqueado No continuará hasta que pueda. No dice qué idioma está usando, pero la mayoría de los idiomas/bibliotecas tienen objetos de bloqueo donde puede "intentar" tomar el bloqueo y luego continuar y hacer algo diferente dependiendo de si tuvo éxito o no.

Pero, por ejemplo, en los bloques sincronizados de Java, el hilo se detendrá hasta que pueda adquirir el monitor (mutex, bloqueo). La interfaz java.util.concurrent.locks.Lock describe objetos de bloqueo que tienen más flexibilidad en términos de adquisición de bloqueo.

6

La manera más simple de pensarlo es que el hilo bloqueado se pone en estado de espera ("durmiendo") hasta que el hilo que lo sujeta libera el mutex. En ese punto, el sistema operativo "activará" uno de los hilos que esperan en el mutex y le permitirá adquirirlo y continuar. Es como si el sistema operativo simplemente coloca el hilo bloqueado en un estante hasta que tenga lo que necesita para continuar. Hasta que el sistema operativo retire el hilo del estante, no está haciendo nada. La implementación exacta - qué hilo pasa a continuación, si todos se despiertan o están en cola - dependerá de su sistema operativo y del idioma/marco que esté utilizando.

+0

Entonces, ¿cuál es exactamente la diferencia entre estar bloqueado o esperando, son lo mismo? – Celeritas

0

Demasiado tarde para responder, pero puedo facilitar la comprensión. Estoy hablando más de perspectiva de implementación que de textos teóricos.

La palabra "bloqueo" es una especie de homónimo técnico.La gente puede usarlo para durmiendo o simplemente esperando. El término debe entenderse en el contexto del uso.

medios de bloqueo de espera - Supongamos en un sistema SMP un hilo Un quiere adquirir un spinlock en poder de algún otro flujo B. Uno de los mecanismos es desactivar tanteo y de seguir girando en el procesador a menos que B lo consigue. Otro mecanismo, probablemente eficiente, es permitir que otros subprocesos usen el procesador, en caso de que B no lo haga en intentos fáciles. Por lo tanto, programamos el hilo B (como prioridad está habilitada) y le damos el procesador a otro hilo C. En este caso, el hilo B simplemente espera en la cola del planificador y regresa con su turno. Comprenda que B no está durmiendo esperando más bien de forma pasiva en lugar de ocupado, espere y queméntese ciclos del procesador. En los sistemas BSD y Solaris existen estructuras de datos como torniquetes para implementar esta situación.

medios de bloqueo para dormir - Si el hilo B en vez había hecho la llamada al sistema como lectura() de datos a la espera de la toma de red, no puede proceder hasta que lo consigue. Por lo tanto, algunos textos usan casualmente el bloqueo de términos como "... bloqueado para E/S" o "... en bloqueo de llamadas al sistema". En realidad, el hilo B está durmiendo. Existen estructuras de datos específicas conocidas como filas de espera, al igual que las salas de espera de lujo en puertos de aire :-). El hilo se activará cuando el sistema operativo detecte la disponibilidad de datos, al igual que un asistente de la sala de espera.

Cuestiones relacionadas