Bloqueos (lock)
A menudo se requiere sincronizar varios procesos paralelos para poder presentar resultados, acceder a ciertos recursos compartidos, etc. de manera que sólo uno de ellos pueda acceder a la vez. Uno de los métodos más habituales para este propósito es el uso del bloqueo o candado (lock).
Creación
El bloqueo es creado con la función Lock(),
el cual se importa desde el módulo multirpocessing:
Uso
Manual
Una forma de usar el bloqueo es mediante el uso manual del bloqueo
con los métodos acquire() y release():
# bloqueo manual
bloqueo.acquire()
# acceso al recurso protegido
numero_compartido.value += 1
# liberacion manual
bloqueo.release()
El método acquire() hace que el bloqueo impida
el acceso a otros procesos
del recurso compartido.
Una vez utilizado el recurso protegido
es indispensable liberar su acceso
llamando al método release(),
de otra manera los otros procesos
quedarán suspendidos indefinidamente.
Con administrador de contexto
Otra forma de usar el bloqueo es con la ayuda de la clásula with:
En este caso el bloqueo y la liberación del recurso se hacen automáticamente.
Ejemplo de uso
Tómese por ejemplo un programa que crea cuatro procesos, los cuales acceden a un recurso compartido y se demoran en ello exactamente 0.5 segundos:
from multiprocessing import Process, Value, Lock
from time import time, sleep
contador = Value('d', 0)
bloqueo = Lock()
def incremento():
"""Se imita una tarea que intenta acceder a un recurso compartido."""
with bloqueo:
# se simula un recurso ocupado o una rutina exigente
sleep(0.5)
# acceso a un recurso compartido
contador.value += 1
tiempo_inicio = time()
# procesos con acceso al recurso compartido
subprocesos = [Process(target=incremento) for n in range(4)]
for proceso in subprocesos:
proceso.start()
# espera al cierre de procesos
for proceso in subprocesos:
proceso.join()
tiempo_fin = time()
print("Tiempo ejecución: %.2f seg" % (tiempo_fin - tiempo_inicio))
print("El número compartido es %d" % (contador.value))
En este ejemplo el resultado es la ejecución concurrente de los procesos debido a que el bloqueo sólo admite el acceso de un proceso a la vez: