2009-09-04 9 views
4

특정 작업을 주기적으로 수행해야하는 xmlrpc 서버에서 작업하고 있습니다. 나는 XMLRPC 서비스의 핵심으로 트위스트 사용하고 있지만 약간의 문제로 실행하고 있습니다 :트위스트 리액터가있는 파이썬 다중 처리

class cemeteryRPC(xmlrpc.XMLRPC): 

    def __init__(self, dic): 
     xmlrpc.XMLRPC.__init__(self) 


    def xmlrpc_foo(self): 
     return 1 


    def cycle(self): 
     print "Hello" 
     time.sleep(3) 


class cemeteryM(base): 

    def __init__(self, dic): # dic is for cemetery 
     multiprocessing.Process.__init__(self) 
     self.cemRPC = cemeteryRPC() 


    def run(self): 
     # Start reactor on a second process 
     reactor.listenTCP(c.PORT_XMLRPC, server.Site(self.cemRPC)) 
     p = multiprocessing.Process(target=reactor.run) 
     p.start() 

     while not self.exit.is_set(): 
      self.cemRPC.cycle() 
      #p.join() 


if __name__ == "__main__": 

    import errno 
    test = cemeteryM() 
    test.start() 

    # trying new method 
    notintr = False 
    while not notintr: 
     try: 
      test.join() 
      notintr = True 
     except OSError, ose: 
      if ose.errno != errno.EINTR: 
       raise ose 
     except KeyboardInterrupt: 
      notintr = True 

가 어떻게 각각의 차단하지 않는 조인 있도록이 두 과정을 참여에 대해 가야하나요?

(I 꽤 "가입"에 의해 혼란 스러워요. 왜 차단하는 것입니다 및 검색 좀했지만 조인의 사용에 많은 도움이 설명을 찾을 수 없습니다. 누군가가 나에게 이것을 설명 할 수 있습니까?)

감사

답변

11

Twisted를 별도의 프로세스로 실행해야합니까? 그것은 나에게 꽤 이상하게 보입니다.

Twisted 's Reactor를 기본 루프로 생각하고 Twisted를 백그라운드 작업으로 실행하는 대신 필요한 모든 것을 중단하십시오.

이러한 종류의 작업을 수행하는 더 일반적인 방법은 Twisted의 .callLater를 사용하거나 LoopingCall 개체를 Reactor에 추가하는 것입니다.

from twisted.web import xmlrpc, server 
from twisted.internet import task 
from twisted.internet import reactor 

class Example(xmlrpc.XMLRPC):   
    def xmlrpc_add(self, a, b): 
     return a + b 

    def timer_event(self): 
     print "one second" 

r = Example() 
m = task.LoopingCall(r.timer_event) 
m.start(1.0) 

reactor.listenTCP(7080, server.Site(r)) 
reactor.run() 
+1

오, 사람 thx 많이 그 이유는 정확하게 필요합니다. LoopingCall에 대한 정보는 어디서 찾았습니까? 이것이 내가 왜곡 된 것을 싫어하는 이유입니다. 문서는 한 손에는 충분하지 않지만 API는 매우 웅장하여 중요한 비트를 간과하는 경향이 있습니다. –

+0

나는 당신이 의미하는 바를 안다. - 뒤틀린 것은 배우기 까다로울 수 있지만 일단 아이디어를 얻으면 그것은 훌륭하게 작동한다! O'Reilly의 책은 꽤 오래되었지만 일을 아주 잘 설명하고 있습니다. 그래서 Twisted로 훨씬 더 많은 것을 할 수 있다면 사본을 얻는 것이 좋습니다. –

+1

메일 링리스트에 가입하는 것이 좋습니다. 전문가의 충분한 답변을 읽으면 일부는 뇌 - 삼투 *를 시작합니다. – DrBloodmoney

3

안녕하세요 asdvawev - 멀티에서 .join()는 단지 스레딩에 .join()처럼 작동 - 그것은 메인 스레드는 작업자가 종료 때까지 기다릴 실행 전화를 차단합니다. 작업자가 종료하지 않으면 .join()이 반환되지 않습니다. 예 :

class myproc(Process): 
    def run(self): 
     while True: 
      time.sleep(1) 

이렇게 실행하면 join()이 절대 반환되지 않습니다. 당신은 단순히 수 - 당신의 작업이 대기열에 캡슐화되어있는 경우

class myproc(Process): 
    def __init__(self, event): 
     self.event = event 
     Process.__init__(self) 
    def run(self): 
     while not self.event.is_set(): 
      time.sleep(1) 

또는 : 일반적으로 나는 종료 할 때 내가 아이를 신호 할 수 있도록 자식 프로세스에 전달 이벤트() 객체를 사용합니다이를 방지하기 위해 (일반적으로 대기열의 없음 항목)을 만나고 종료 될 때까지 대기열에서 자식 프로세스가 작동하도록합니다.

이러한 제안은 .join()을 호출하기 전에 이벤트를 보내거나 sentinel을 삽입 할 수 있으며 join()이 호출되면 프로세스가 현재 작업을 마친 다음 제대로 종료된다는 것을 의미합니다.

관련 문제