2011-03-15 8 views
1

저는 파이썬으로 간단한 클라이언트 - 서버 애플리케이션을 개발하고 있습니다. 공유 대기열을 설정하기 위해 관리자를 사용하고 있지만 서버에서 클라이언트로 임의의 객체를 전달하는 방법을 알 수 없습니다. 나는 그것이 manager.register 함수와 관련이 있다고 의심하지만, multiprocessing documentation에는 그다지 잘 설명되어 있지 않다. 유일한 예제는 Queues와 다른 것을 사용합니다.원격 관리자를 사용하여 파이썬 객체를 전달하는 방법은 무엇입니까?

#manager demo.py 
from multiprocessing import Process, Queue, managers 
from multiprocessing.managers import SyncManager 
import time 

class MyObject(): 
    def __init__(self, p, f): 
     self.parameter = p 
     self.processor_function = f 

class MyServer(): 
    def __init__(self, server_info, obj): 
     print '=== Launching Server ... =====' 
     (ip, port, pw) = server_info 
     self.object = obj  #Parameters for task processing 

     #Define queues 
     self._process_queue = Queue()  #Queue of tasks to be processed 
     self._results_queue = Queue()  #Queue of processed tasks to be stored 

     #Set up IS_Manager class and register server functions 
     class IS_Manager(managers.BaseManager): pass 
     IS_Manager.register('get_processQ', callable=self.get_process_queue) 
     IS_Manager.register('get_resultsQ', callable=self.get_results_queue) 
     IS_Manager.register('get_object', callable=self.get_object) 

     #Initialize manager and server 
     self.manager = IS_Manager(address=(ip, port), authkey=pw) 
     self.server = self.manager.get_server() 

     self.server_process = Process(target=self.server.serve_forever) 
     self.server_process.start() 

    def get_process_queue(self): return self._process_queue 
    def get_results_queue(self): return self._results_queue 
    def get_object(self): return self.object 

    def runUntilDone(self, task_list): 
     #Fill the initial queue 
     for t in task_list: 
      self._process_queue.put(t) 

     #Main loop 
     total_tasks = len(task_list) 
     while not self._results_queue.qsize()==total_tasks: 
      time.sleep(.5) 
      print self._process_queue.qsize(), '\t', self._results_queue.qsize() 
      if not self._results_queue.empty(): 
       print '\t', self._results_queue.get() 
      #Do stuff 
      pass 

class MyClient(): 
    def __init__(self, server_info): 
     (ip, port, pw) = server_info 
     print '=== Launching Client ... =====' 

     class IS_Manager(managers.BaseManager): pass 

     IS_Manager.register('get_processQ') 
     IS_Manager.register('get_resultsQ') 
     IS_Manager.register('get_object') 

     #Set up manager, pool 
     print '\tConnecting to server...' 
     manager = IS_Manager(address=(ip, port), authkey=pw) 
     manager.connect() 

     self._process_queue = manager.get_processQ() 
     self._results_queue = manager.get_resultsQ() 
     self.object = manager.get_object() 

     print '\tConnected.' 

    def runUntilDone(self):#, parameters): 
     print 'Starting client main loop...' 

     #Main loop 
     while 1: 
      if self._process_queue.empty(): 
       print 'I\'m bored here!' 
       time.sleep(.5) 
      else: 
       task = self._process_queue.get() 
       print task, '\t', self.object.processor_function(task, self.object.parameter) 

     print 'Client process is quitting. Bye!' 
     self._clients_queue.get() 

그리고 간단한 서버 ...

from manager_demo import * 

def myProcessor(x, parameter): 
    return x + parameter 

if __name__ == '__main__': 
    my_object = MyObject(100, myProcessor) 
    my_task_list = range(1,20) 
    my_server_info = ('127.0.0.1', 8081, 'my_pw') 

    my_crawl_server = MyServer(my_server_info, my_object) 
    my_crawl_server.runUntilDone(my_task_list) 

그리고 간단한 클라이언트 ... 내가 이것을 실행하면

from manager_demo import * 
if __name__ == '__main__': 
    my_server_info = ('127.0.0.1', 8081, 'my_pw') 
    my_client = MyClient(my_server_info) 
    my_client.runUntilDone() 

이가 충돌 : 여기

내 코드입니다 :

[email protected]:~/Desktop$ python client.py 
=== Launching Client ... ===== 
    Connecting to server... 
    Connected. 
Starting client main loop... 
2 Traceback (most recent call last): 
    File "client.py", line 5, in <module> 
    my_client.runUntilDone() 
    File "/home/erin/Desktop/manager_demo.py", line 84, in runUntilDone 
    print task, '\t', self.object.processor_function(task, self.object.parameter) 
AttributeError: 'AutoProxy[get_object]' object has no attribute 'parameter' 

왜 파이썬은 대기열 또는 processor_function과 관련하여 문제가 없지만 객체 매개 변수를 질식합니까? 감사!

답변

2

MyObject() 클래스의 parameter 속성이 호출 가능하지 않기 때문에이 문제가 발생합니다.

documentation에는 _exposed_이이 typeid를 위임하는 일련의 메서드 이름을 지정하는 데 사용됩니다. 공개 목록이 지정되지 않은 경우 공유 객체의 모든 "공용 메소드"에 액세스 할 수 있습니다. (여기에 "공개 방법은"이름이 '_'로 시작하지 않는 __ 전화 __() 메소드가있는 모든 속성을 의미한다.) 그래서

수동으로 parameter가 속성을 노출해야합니다 MyObject, 아마도, 방법으로, 변경하여 MyObject() : 또한

class MyObject(): 
    def __init__(self, p, f): 
     self._parameter = p 
     self.processor_function = f 

    def parameter(self): 
     return self._parameter 

, 당신은 당신의 작업을 변경해야합니다 :

self.object.processor_function(task, self.object.parameter()) 

HTH를.