RedNotes
Toggle sidebar
Iniciar sesión
Sistemas Operativos/Mutex y monitores
Inicia sesión para editar

Primitivas de sincronización derivadas de los Sistemas Operativos/Semáforos, pensadas para resolver la Sistemas Operativos/Concurrencia de forma más simple y menos propensa a errores.

Mutex

Un mutex es una versión simplificada del semáforo, sin capacidad de contar. Tiene dos estados: abierto o cerrado.

  • mutex_lock: si está abierto, lo cierra y el hilo entra a la región crítica. Si está cerrado, el hilo se bloquea.
  • mutex_unlock: lo abre; si hay hilos bloqueados, se elige uno al azar.

Implementación de Tanenbaum para hilos en espacio de usuario (con TSL):

mutex_lock:
    TSL REGISTER,MUTEX
    CMP REGISTER,0
    JZE ok              | si era 0, estaba abierto: regresar
    CALL thread_yield   | ocupado: planificar otro hilo
    JMP mutex_lock
ok: RET
mutex_unlock:
    MOVE MUTEX,0
    RET

La diferencia con enter_region es que no hace espera ocupada: cede la CPU.

Futex (Linux)

Un futex (fast user space mutex) evita entrar al Sistemas Operativos/Kernel cuando no hay contención: el candado se toma con una operación atómica en espacio de usuario y sólo se llama al kernel para bloquearse si está ocupado.

Pthreads

Llamada Descripción
pthread_mutex_init / destroy Crear / destruir mutex
pthread_mutex_lock Adquirir o bloquearse
pthread_mutex_trylock Adquirir o fallar sin bloquearse
pthread_mutex_unlock Liberar

Variables de condición

Permiten que un hilo se bloquee hasta que se cumpla una condición. Se usan siempre junto con un mutex.

  • pthread_cond_wait(&cond, &mutex): libera el mutex atómicamente y se bloquea.
  • pthread_cond_signal(&cond): despierta a un hilo.
  • pthread_cond_broadcast(&cond): despierta a todos.

A diferencia de los semáforos, no tienen memoria: si se señala una variable de condición sin nadie esperando, la señal se pierde. Por eso se espera siempre dentro de un while que revisa la condición.

Monitores

Propuestos por Hoare (1974) y Brinch Hansen (1975). Un monitor es una colección de procedimientos, variables y estructuras de datos agrupados en un módulo especial, con una propiedad clave:

Sólo un proceso puede estar activo dentro del monitor en un instante dado.

La exclusión mutua la garantiza el compilador, no el programador, eliminando los errores de orden típicos de los semáforos.

Dentro del monitor se usan variables de condición con wait y signal. Ante un signal:

  • Hoare: el proceso despertado se ejecuta inmediatamente y el que señaló se suspende.
  • Brinch Hansen: signal debe ser la última instrucción del procedimiento.
  • Mesa: el que señala continúa; el despertado compite después (requiere while).

Productor-consumidor con monitor (pseudo-Pascal)

monitor ProducerConsumer
    condition full, empty;
    integer count;

    procedure insert(item: integer);
    begin
        if count = N then wait(full);
        insert_item(item);
        count := count + 1;
        if count = 1 then signal(empty)
    end;

    function remove: integer;
    begin
        if count = 0 then wait(empty);
        remove = remove_item;
        count := count - 1;
        if count = N - 1 then signal(full)
    end;

    count := 0;
end monitor;

Monitores en Java

Java soporta monitores con synchronized en métodos, más wait(), notify() y notifyAll().

Limitaciones

Monitores y semáforos asumen memoria compartida. En sistemas distribuidos se usa paso de mensajes.

Ver Sistemas Operativos/Problemas clásicos de IPC.

#sistemas-operativos #tanenbaum #concurrencia #mutex