Python在进程之间共享锁
我正在尝试使用部分函数,以便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()
但是,当我运行此代码时,出现错误:
Runtime Error: Lock objects should only be shared between processes through inheritance.
我在这里想念什么?如何在子流程之间共享锁?
-
您不能将普通
multiprocessing.Lock
对象传递给Pool
方法,因为它们不能被腌制。有两种方法可以解决此问题。一种是创建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()
不过,这有点重量级;使用
Manager
需要产生另一个进程来托管Manager
服务器。并且所有对acquire
/release
锁的调用都必须通过IPC发送到该服务器。另一种选择是
multiprocessing.Lock()
使用initializer
kwarg在创建池时传递常规值。这将使您的锁实例在所有子工作者中都是全局的: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()
第二种解决方案具有不再需要的副作用
partial
。