Python:为什么这里的进程之间共享多处理锁?

gdR*_*Row 4 python locking multiprocessing python-3.x shared-variable

我试图在进程之间共享一个锁。我知道共享锁的方法是将其作为参数传递给目标函数。但是我发现,即使下面的方法也有效。我无法理解进程共享此锁的方式。有人可以解释吗?

import multiprocessing as mp
import time


class SampleClass:

    def __init__(self):
        self.lock = mp.Lock()
        self.jobs = []
        self.total_jobs = 10

    def test_run(self):
        for i in range(self.total_jobs):
            p = mp.Process(target=self.run_job, args=(i,))
            p.start()
            self.jobs.append(p)

        for p in self.jobs:
            p.join()

    def run_job(self, i):
        with self.lock:
            print('Sleeping in process {}'.format(i))
            time.sleep(5)


if __name__ == '__main__':
    t = SampleClass()
    t.test_run()
Run Code Online (Sandbox Code Playgroud)

Tim*_*ers 5

在Windows(您说过您正在使用)上,这类事情总是会简化为有关如何multiprocessing使用的细节pickle,因为Windows上所有Python数据跨越进程的边界都是通过在发送端进行酸洗(在接收端进行酸洗)来实现的。 。

我最好的建议是避免做任何会引起此类问题的事情;-)例如,您显示的代码在Windows下使用Python 2炸毁,在Python 3下使用multiprocessing.Pool方法(而不是)炸毁multiprocessing.Process。

这不仅是锁,还只是试图使self.run_jobPython 2中的绑定方法(如)失效,请考虑一下。您正在跨越流程边界,并且在接收端没有对应的对象self。self.run_job在接收端应该绑定到什么对象?

在Python 3中,酸洗self.run_job 还会酸洗self对象的副本。这就是答案:SampleClass与之相对应的对象self是在接收端由魔术创建的。清澈如泥。 t的整个状态被腌制,包括t.lock。这就是它“起作用”的原因。

请参阅此以获取更多实施细节:

为什么我可以将实例方法传递给multiprocessing.Process,而不是multiprocessing.Pool?

从长远来看,如果您坚持那些显然可以工作的事情,那么您将蒙受最少的谜团:传递模块全局可调用对象(无论是实例方法还是本地函数),并显式传递multiprocessing数据对象(无论是实例Lock,Queue,manager.list,等等等等)。