set_start_method - python pool thread
Python compartiendo un bloqueo entre procesos (1)
Lo siento, debería haber entendido esto en mi respuesta a tu otra pregunta. No puede pasar el multiprocessing.Lock
normal. multiprocessing.Lock
objetos en los métodos Pool
, ya que no se pueden escalar. Hay dos formas de evitar esto. Una es crear Manager()
y pasar un Manager.Lock()
:
def main():
iterable = [1, 2, 3, 4, 5]
pool = multiprocessing.Pool()
m = multiprocessing.Manager()
l = m.Lock()
func = partial(target, l)
pool.map(func, iterable)
pool.close()
pool.join()
Sin embargo, esto es un poco pesado; utilizar un Manager
requiere generar otro proceso para alojar el servidor de Manager
. Y todas las llamadas para acquire
/ release
el bloqueo deben enviarse a ese servidor a través de IPC.
La otra opción es pasar el multiprocessing.Lock()
regular. Bloquear multiprocessing.Lock()
en el tiempo de creación del grupo, usando el kwarg del initializer
. Esto hará que su instancia de bloqueo sea global en todos los niños trabajadores:
def target(iterable_item):
for item in items:
# Do cool stuff
if (... some condition here ...):
lock.acquire()
# Write to stdout or logfile, etc.
lock.release()
def init(l):
global lock
lock = l
def main():
iterable = [1, 2, 3, 4, 5]
l = multiprocessing.Lock()
pool = multiprocessing.Pool(initializer=init, initargs=(l,))
pool.map(target, iterable)
pool.close()
pool.join()
La segunda solución tiene el efecto secundario de no requerir más partial
.
Estoy intentando usar una función parcial para que pool.map () pueda apuntar a una función que tenga más de un parámetro (en este caso un objeto Lock ()).
Aquí hay un código de ejemplo (tomado de una respuesta a una pregunta previa mía):
from functools import partial
def target(lock, iterable_item):
for item in items:
# Do cool stuff
if (... some condition here ...):
lock.acquire()
# Write to stdout or logfile, etc.
lock.release()
def main():
iterable = [1, 2, 3, 4, 5]
pool = multiprocessing.Pool()
l = multiprocessing.Lock()
func = partial(target, l)
pool.map(func, iterable)
pool.close()
pool.join()
Sin embargo, cuando ejecuto este código, obtengo el error:
Runtime Error: Lock objects should only be shared between processes through inheritance.
¿Que me estoy perdiendo aqui? ¿Cómo puedo compartir el bloqueo entre mis subprocesos?