Python多处理模块:在进程内调用实例方法

Python多处理模块:在进程内调用实例方法,python,multiprocessing,pickle,Python,Multiprocessing,Pickle,基于Python的多处理模块,我需要执行以下操作: -创建一个不断运行的进程,该进程可能会被特定事件中断 -在此过程中,从客户端接收消息,并将此消息传递给对象实例的处理程序方法 基本代码如下(省略了一些细节)。问题是我试图调用实例方法(self.enroll(message),但没有效果,正如预期的那样。我知道原因-进程使用自己的内存等-我已经实现了中介绍的解决方案,用于解决酸洗有界方法的问题,并尝试了使用管理器、队列、池的不同方法…由于没有任何方法起作用,我决定将代码作为“原始”代码尽可能,以

基于Python的多处理模块,我需要执行以下操作:

-创建一个不断运行的进程,该进程可能会被特定事件中断

-在此过程中,从客户端接收消息,并将此消息传递给对象实例的处理程序方法

基本代码如下(省略了一些细节)。问题是我试图调用实例方法(self.enroll(message),但没有效果,正如预期的那样。我知道原因-进程使用自己的内存等-我已经实现了中介绍的解决方案,用于解决酸洗有界方法的问题,并尝试了使用管理器、队列、池的不同方法…由于没有任何方法起作用,我决定将代码作为“原始”代码尽可能,以便你能理解我的意图。欢迎任何帮助

class DistManager:
    def __init__(self, name, network_address, password):
        self.name = name
        self.network_address = network_address
        self.password = password
        self.distribution_clients = {}

    def _run_distribution_process(self):
        import select
        while not self.should_stop_distribution_service.is_set():
            (sread, swrite, sexc) = select.select([self.distribution_listener], [], [], 0)
            if (sread):
                connection = self.distribution_listener.accept()
                serialized_message = connection.recv()  # currently only receiving
                connection.close()
                message = pickle.loads(serialized_message)
                self.enroll(message)  # THE PROBLEM IS HERE

    def start_distribution_service(self, distribution_port):
        self.distribution_port = distribution_port
        # patch for making Listener work with select.select during run
        Listener.fileno = lambda self: self._listener._socket.fileno()
        self.distribution_listener = Listener(address=(self.network_address, self.distribution_port),
                                              authkey=self.password)
        self.should_stop_distribution_service = Event()
        self.distribution_process = Process(name='Distribution Runner', target=self._run_distribution_process)
        self.distribution_process.daemon = True
        self.distribution_process.start()

    def stop_distribution_service(self):
        from time import sleep
        self.should_stop_distribution_service.set()
        sleep(1)
        self.distribution_listener.close()
        self.distribution_process.terminate()
        return self.distribution_process.exitcode

    def _enroll_distribution_client(self, identifier, network_address, phone_number):
        self.distribution_clients[identifier] = (network_address, phone_number)

    def enroll(self, message):
        if type(message.content) is tuple:
            self._enroll_distribution_client(message.generator_identifier, message.content[0], message.content[1])
        else:
            raise TypeError("Tuple expected")
        return message.code

您仍然可以对此使用multiprocessing.pool,而不会出现酸洗错误

将以下行添加到对该类进行多处理的代码中,您仍然可以通过池传递该方法

import copy_reg
    import types

    def _reduce_method(meth):
        return (getattr,(meth.__self__,meth.__func__.__name__))
    copy_reg.pickle(types.MethodType,_reduce_method)

有关如何pickle方法的更多理解,请参见下面的注释:一种解决方案是在流程内实例化对象,但事实并非如此,出于其他原因,我需要调用流程外创建的实例的方法-这是中心点。