[英]Python Multiprocessing Module: calling an instance method within a process
基于Python的多处理模块,我需要做以下事情:
- 创建一个可以被特定事件中断的正在运行的进程。
- 在此过程中,从客户端接收消息,并将此消息传递给对象实例的处理程序方法。
基本代码如下(省略一些细节)。 问题是我尝试调用实例方法(self.enroll(message),但没有效果,正如预期的那样。我知道原因 - 进程使用自己的内存等 - 我已经实现了当使用python的多处理Pool.map()解决绑定有界方法的问题,以及尝试使用Manager,Queue,Pool的不同方法时, 无法挑选<type'instancemethod'> ,因为没有工作,我决定把代码尽可能“原始”,以便你能理解我的意图。欢迎任何帮助。
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,而不会出现pickling错误。
将以下行添加到与该类进行多处理的代码中,您仍然可以通过池传递该方法。 代码应该高于班级
import copy_reg
import types
def _reduce_method(meth):
return (getattr,(meth.__self__,meth.__func__.__name__))
copy_reg.pickle(types.MethodType,_reduce_method)
有关如何挑选方法的更多信息,请参阅下面的http://docs.python.org/2/library/copy_reg.html
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.