DJM*_*y12 41 python share locking multiprocessing
我试图使用部分函数,以便pool.map()可以定位具有多个参数的函数(在本例中为Lock()对象).
这是示例代码(取自我之前的一个问题的答案):
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()
Run Code Online (Sandbox Code Playgroud)
但是,当我运行此代码时,我收到错误:
Runtime Error: Lock objects should only be shared between processes through inheritance.
Run Code Online (Sandbox Code Playgroud)
我在这里错过了什么?如何在子进程之间共享锁?
dan*_*ano 80
对不起,我应该在回答你的另一个问题时发现这一点.您无法将普通multiprocessing.Lock对象传递给Pool方法,因为它们无法进行pickle.有两种方法可以解决这个问题.一个是创建Manager()并传递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()
Run Code Online (Sandbox Code Playgroud)
不过,这有点重量级; 使用a Manager需要生成另一个进程来托管Manager服务器.所有对acquire/ releaselock的调用都必须通过IPC发送到该服务器.
另一种选择是multiprocessing.Lock()使用initializerkwarg 在Pool创建时传递常规.这将使您的锁实例在所有子工作者中全局:
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()
Run Code Online (Sandbox Code Playgroud)
第二种解决方案具有不再需要的副作用partial.