5

特定のタスクを周期的に実行する必要があるxmlrpcサーバーで作業しています。私は xmlrpc サービスのコアとして twisted を使用していますが、ちょっとした問題が発生しています:

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 つのプロセスに結合するにはどうすればよいですか?

(私は「結合」にかなり混乱しています。なぜそれがブロックされ、グーグルで検索しましたが、結合の使用法についてあまり役立つ説明が見つかりません。誰かが私にこれを説明できますか?)

よろしく

4

2 に答える 2

11

本当に別のプロセスでツイストを実行する必要がありますか?それは私にはかなり珍しいように見えます。

Twistedをバックグラウンドタスクとして実行するのではなく、TwistedのReactorをメインループと考えて、必要なものをすべてハングアップしてください。

この種の操作を実行するより一般的な方法は、Twistedの.callLaterを使用するか、RoopingCallオブジェクトを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()
于 2009-09-04T12:06:34.700 に答える
3

asdvawev - マルチプロセッシングの .join() は、スレッドの .join() と同じように機能します。これは、ワーカーがシャットダウンするのを待つためにメイン スレッドが実行するブロッキング呼び出しです。ワーカーがシャットダウンしない場合、.join() は戻りません。例えば:

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

これで run を呼び出すと、 join() が決して返されないことを意味します。通常、これを防ぐために、子プロセスに渡される Event() オブジェクトを使用して、いつ終了するかを子プロセスに通知できるようにします。

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)

または、作業がキューにカプセル化されている場合は、子プロセスがセンチネル (通常はキュー内の None エントリ) に遭遇するまでキューから離れて動作し、その後シャットダウンすることができます。

これらの提案はどちらも、.join() を呼び出す前に、イベントを送信するか、番兵を挿入することができ、join() が呼び出されると、プロセスは現在のタスクを終了してから適切に終了することを意味します。

于 2009-09-04T13:29:24.070 に答える