3 回答
TA贡献1839条经验 获得超15个赞
抱歉,我应该已经回答您其他问题了。您不能将普通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()使用initializerkwarg 在创建池时传递常规值。这将使您的锁实例在所有子工作者中都是全局的:
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。
TA贡献1825条经验 获得超4个赞
multiprocessing.Lock
是一个进程安全的对象,因此您可以将其直接传递给子进程,并在所有子进程中安全地使用它。但是,大多数可变的Python对象(例如list
,,dict
大多数用户创建的类)都不安全,因此在进程之间传递它们会导致在每个进程中创建对象的完全不同的副本。在这种情况下,您需要使用multiprocessing.Manager
。
添加回答
举报