将 Lock 对象传递给继承 multiprocessing.Process 的 class

Pass Lock object to class that inherits multiprocessing.Process

如何将 Lock 对象传递给 multiprocessing.Process 的子类?我试过了,但遇到了酸洗错误。

from multiprocessing import Process
from threading import Lock

class myProcess (Process):

    def setLock (self , lock) :
        self.lock = lock

    def run(self) :
        with self.lock :
            # do stuff

if __name__ == '__main__' :
    lock = Lock()
    proc1 = myProcess()
    proc1.setLock(lock)

    proc2 = myProcess()
    proc2.setLock(lock)

    proc1.start()
    proc2.start()

有很多关于将锁传递给 multiprocessing.Pool 的已回答问题,但其中 none 解决了我使用 Process 的 OOP 方法的问题。如果我想做一个全局锁,我应该在哪里定义它,我在哪里可以将它传递给 myProcess 个对象?

您不能使用 threading.Lock 进行多处理,您需要使用 multiprocessing.Lock

你得到 pickling-error 因为 threading.Lock 不能被 pickle 而你在 OS 上使用 "spawn" 作为启动新进程的默认值(Windows 或 macOS 与 Python 3.8+).

请注意,在分叉 OS(Linux、BSD...)时,使用 threading.Lock,您不会收到酸洗错误,但锁会静默复制,不提供您想要的进程之间的同步。

可以使用单独的函数来设置锁定,但我更愿意将它作为参数传递给 Process.__init__() 以及其他可能的参数。

import time
from multiprocessing import Process, Lock, current_process


class MyProcess(Process):

    def __init__(self, lock, name=None, args=(), kwargs={}, daemon=None):
        super().__init__(
            group=None, name=name, args=args, kwargs=kwargs, daemon=daemon
        )
        # `args` and `kwargs` are stored as `self._args` and `self._kwargs`
        self.lock = lock

    def run(self) :
        with self.lock :
            for i in range(3):
                print(current_process().name, *self._args)
                time.sleep(1)


if __name__ == '__main__' :

    lock = Lock()
    p1 = MyProcess(lock=lock, args=("hello",))
    p2 = MyProcess(lock=lock, args=("world",))

    p1.start()
    p2.start()

    p1.join()  # don't forget joining to prevent parent from exiting too soon.
    p2.join()

输出:

MyProcess-1 hello
MyProcess-1 hello
MyProcess-1 hello
MyProcess-2 world
MyProcess-2 world
MyProcess-2 world

Process finished with exit code 0