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.

我在这里想念什么?如何在子流程之间共享锁?


不负相思意
浏览 701回答 3
3回答

紫衣仙女

抱歉,我应该已经回答您其他问题了。您不能将普通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 = ldef 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。

凤凰求蛊

multiprocessing.Lock是一个进程安全的对象,因此您可以将其直接传递给子进程,并在所有子进程中安全地使用它。但是,大多数可变的Python对象(例如list,,dict大多数用户创建的类)都不安全,因此在进程之间传递它们会导致在每个进程中创建对象的完全不同的副本。在这种情况下,您需要使用multiprocessing.Manager。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python