首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Python在进程之间共享锁

Python在进程之间共享锁
EN

Stack Overflow用户
提问于 2014-08-29 04:43:01
回答 2查看 63.5K关注 0票数 66

我正在尝试使用分部函数,以便pool.map()可以针对具有多个参数的函数(在本例中是Lock()对象)。

以下是示例代码(摘自我之前问题的答案):

代码语言:javascript
运行
复制
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()

然而,当我运行这段代码时,我得到了错误:

代码语言:javascript
运行
复制
Runtime Error: Lock objects should only be shared between processes through inheritance.

这里我漏掉了什么?我如何在我的子进程之间共享锁?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-08-29 05:29:06

您不能将普通的multiprocessing.Lock对象传递给Pool方法,因为它们不能被pickled。有两种方法可以解决这个问题。一种方法是创建Manager()并传递Manager.Lock()

代码语言:javascript
运行
复制
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发送到该服务器。

另一种选择是在池创建时使用initializer multiprocessing.Lock()传递常规的kwarg。这将使您的锁实例在所有子工作器中都是全局的:

代码语言:javascript
运行
复制
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

票数 127
EN

Stack Overflow用户

发布于 2018-09-04 18:09:59

这里有一个版本(使用Barrier而不是Lock,但你明白了),它也可以在Windows上运行(丢失的fork正在造成额外的麻烦):

代码语言:javascript
运行
复制
import multiprocessing as mp

def procs(uid_barrier):
    uid, barrier = uid_barrier
    print(uid, 'waiting')
    barrier.wait()
    print(uid, 'past barrier')    

def main():
    N_PROCS = 10
    with mp.Manager() as man:
        barrier = man.Barrier(N_PROCS)
        with mp.Pool(N_PROCS) as p:
            p.map(procs, ((uid, barrier) for uid in range(N_PROCS)))

if __name__ == '__main__':
    mp.freeze_support()
    main()
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25557686

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档