2013-10-31 2 views
6

내에서 인스턴스 메서드를 호출, 나는 다음을 수행해야합니다파이썬 멀티 모듈 : 파이썬의 멀티 모듈을 기반으로 프로세스

-Create 특정 이벤트에 의해 중단 될 수있는 지금 실행중인 프로세스.

-이 프로세스에서 클라이언트로부터 메시지를 받고이 메시지를 개체 인스턴스의 처리기 메서드에 전달합니다.

기본 코드는 아래에 있습니다 (일부 생략). 문제는 인스턴스 메소드 (self.enroll (message))를 호출하려고하지만 예상대로 효과가 없다는 것입니다. 프로세스가 자체 메모리를 사용하는 등의 이유를 알고 있으며 이미 구현 된 솔루션을 구현했습니다. Can't pickle <type 'instancemethod'> when using python's multiprocessing Pool.map() 바운드 된 메서드의 pickling 문제를 해결하기 위해뿐만 아니라 관리자, 대기열, 풀을 사용하여 시도한 다른 접근법 ... 아무도 작동하지 않기 때문에 코드를 가능한 한 "원시"로 지정하기로 결정하여 내 의도를 이해할 수 있습니다. 어떤 도움을 환영합니다.

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

발언은 아래를 참조하시기 바랍니다 방법을 피클하는 방법에 대한 자세한 이해의 클래스

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

이상 가야한다 : 하나 개의 솔루션은 프로세스 내부의 객체를 생성하는 것입니다, 그러나 이것은 사실이 아니다 다른 이유로, 프로세스 외부에서 생성 된 인스턴스의 메서드를 호출해야합니다. 이것이 바로 핵심 요소입니다. –

답변

1

당신은 여전히 ​​오류를 산 세척하지 않고 이것에 대한 multiprocessing.pool을 사용할 수 있습니다.

클래스와 멀티 프로세싱 않는 코드에 다음 줄을 추가하고 캘리포니아 n은 여전히 ​​풀을 통해 메서드를 전달합니다. 코드는 http://docs.python.org/2/library/copy_reg.html

관련 문제