2009-09-04 38 views
4

私は、特定のタスクを周期的に実行する必要があるxmlrpcサーバで作業しています。私はXMLRPCサービスの中核として、ツイスト使用していますが、私は少し問題に実行しています:ツイストのリアクタを使用したPythonマルチプロセッシング

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 

は、どのように私は、それぞれがブロックされない加入ように、これらの2つのプロセスへの参加については行くべき?

(私は「参加する」ことでかなり混乱しています。なぜ、それがブロックされると私はGoogleで検索しましたが、参加の使用に非常に有用な説明を見つけることができません。誰かが私にこれを説明することはできますか?)

よろしく

答えて

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

ああ、私は正確に必要なのです。 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()を呼び出すと、プロセスが現在のタスクを終了して正常終了することを意味します。

関連する問題