2013-10-31 137 views
6

在實例方法,我需要做到以下幾點:Python的多處理模塊:調用基於Python的多模塊上的進程

- 創建一個不斷運行的過程中,它可以通過一個特定的事件被中斷。

- 在此過程中,接收來自客戶端的消息,並將此消息傳遞給對象實例的處理程序方法。

基本代碼如下(部分細節略)。問題是我嘗試調用實例方法(self.enroll(message)),但沒有任何效果,我知道原因 - 進程使用自己的內存等 - 而且我已經實現瞭解決方案Can't pickle <type 'instancemethod'> when using python's multiprocessing Pool.map()用於解決酸洗有界方法的問題,並嘗試了使用Manager,Queue,Pool ...的不同方法,因爲沒有人工作,我決定儘可能地將代碼放在「原始」位置,這樣您就可以理解我的意圖。任何幫助是值得歡迎的。

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 
+0

的一句話:一個解決方案是實例化進程中的對象,但這種情況並非如此,由於其他原因,我需要調用在流程外部創建的實例的方法 - 這是中心點。 –

回答

1

您仍然可以使用multiprocessing.pool此不酸洗錯誤。

以下行添加到不帶班多處理代碼,你CA ñ仍然通過池中的方法。代碼應該去的類

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