2

ツイストを使用してクライアントをサーバーに接続しています。クライアントには、バックグラウンドで実行している可能性のあるスレッドがあります。原子炉が停止するとき、私は次のことをしなければなりません:

1) check if the thread is doing things
2) stop it if it is

これを行うためのエレガントな方法は何ですか? 私ができる最善のことは、次のような混乱したことです。

def cleanup(self):
    isWorkingDF = defer.Deferred()
    doneDF = defer.Deferred()

    def checkIsWorking():
        res = self.stuff.isWorking() #blocking call
        reactor.callFromThread(isWorkingDF.callback, res)

    def shutdownOrNot(isWorking):
        if isWorking:
            #shutdown necessary, shutdown is also a blocking call
            def shutdown():
                self.stuff.shutdown()
                reactor.callFromThread(doneDF, None)
            reactor.callInThread(shutdown)                
        else:
            doneDF.callback(None) #no shutdown needed

    isWorkingDF.addCallback(shutdownOrNot)

    reactor.callInThread(checkIsWorking)

    return doneDF

まず、それがまったく機能しているかどうかを確認します。そのコールバックの結果は、rescallbackシャットダウンするかしないかのいずれかに入り、その後、閉じるまでツイスト待機する doneDF を起動します。

かなりめちゃめちゃです!より良い方法はありますか?

おそらく関連する質問は、コールバックを相互にチェーンするよりエレガントな方法はありますか? これが完了した後、さらにクリーンアップ コードを実行する必要があることがわかったので、別のdonedeferred を作成し、現在のコールバックを起動して、処理を実行してからdeferreddoneDFを呼び出す必要があります。done

4

3 に答える 3

6

本当の答えは、defer.inlineCallbacksデコレータを使用することです。上記のコードは次のようになります。

@defer.inlineCallbacks
def procShutdownStuff(self):
    isWorking = yield deferToThread(self.stuff.isWorking)

    if isWorking:
        yield deferToThread(self.stuff.shutdown)

def cleanup(self):
    return self.procShutdownStuff()
于 2010-09-15T20:32:21.640 に答える
5

/ペアdeferToThreadの代わりに使用することで、これをいくらか単純化できます。callInThreadcallFromThread

from twisted.internet.threads import deferToThread

def cleanup(self):
    isWorkingDF = deferToThread(self.stuff.isWorking)

    def shutdownOrNot(isWorking):
        if isWorking:
            #shutdown necessary, shutdown is also a blocking call
            return deferToThread(self.stuff.shutdown)

    isWorkingDF.addCallback(shutdownOrNot)

    return isWorkingDF

deferToThread基本的には、関数のバージョンで 2 回実装した同じスレッド ロジックの優れたラッパーです。

于 2010-08-11T22:23:47.183 に答える
0

リアクターをシャットダウンした後にプログラムが終了する場合は、スレッドをデーモン スレッドにすることができます。すべての非デーモン スレッドが終了すると、これは自動的に終了します。daemon = Truestart() を呼び出す前にスレッド オブジェクトに設定するだけです。

これが実行できない場合、たとえば、スレッドが終了する前にリソースのクリーンアップを行う必要がある場合は、リアクターとスレッドの間でキューを使用して通信できます。実行する作業を Queue オブジェクトにプッシュし、スレッドにそれを引き抜いて実行させます。スレッドを終了する必要があることを示すために、特別な「FINISH」トークン (または単に None) を用意します。

于 2010-08-11T20:55:38.753 に答える