Monitor
Los monitor son una herramienta valiosa en programación concurrente y han sido ampliamente adoptados en diversos contextos para gestionar la concurrencia de manera segura y eficiente.
Suponga que se quiere implementar un contador que puede ser incrementado y decrementado por varios hilos simultáneamente, pero se debe asegurar de que estas operaciones sean atómicas y que siempre se respete la exclusión mutua.
Codificación
import threading class MonitorContador: def __init__(self): self.valor = 0 self.mutex = threading.Lock() def incrementar(self): with self.mutex: self.valor += 1 def decrementar(self): with self.mutex: self.valor -= 1 def obtener_valor(self): with self.mutex: return self.valor # Crear una instancia del monitor contador_monitor = MonitorContador() # Definir una función que incrementa el contador def aumentar_contador(): for _ in range(1000000): contador_monitor.incrementar() # Definir una función que decrementa el contador def disminuir_contador(): for _ in range(1000000): contador_monitor.decrementar() # Crear hilos para incrementar y decrementar el contador hilo_aumentar = threading.Thread(target=aumentar_contador) hilo_disminuir = threading.Thread(target=disminuir_contador) # Iniciar los hilos hilo_aumentar.start() hilo_disminuir.start() # Esperar a que ambos hilos terminen hilo_aumentar.join() hilo_disminuir.join() # Obtener el valor final del contador desde el monitor valor_final = contador_monitor.obtener_valor() print("Valor final del contador:", valor_final)
Explicación
En este ejemplo, la clase MonitorContador
encapsula el contador y los métodos (incrementar
, decrementar
, obtener_valor
) que operan sobre él. Se utiliza un cerrojo (mutex
) para garantizar la exclusión mutua alrededor de las operaciones críticas. Los dos hilos (hilo_aumentar
y hilo_disminuir
) realizan incrementos y decrementos en paralelo, pero gracias al monitor, estas operaciones son seguras y el valor final del contador reflejará la suma y resta correctamente.