3

私はノンブロッキングIOの概念に不慣れで、コルーチンについて理解するのに苦労しています。このコードを検討してください:

class UserPostHandler(RequestHandler):
    @gen.coroutine
    def get(self):
        var = 'some variable'
        data = json.loads(self.request.body)
        yield motor_db.users.insert({self.request.remote_ip: data})#asynch non blocking db insert call
        #success
        self.set_status(201)
        print var

get関数が呼び出されると、 string が作成されますvarmotor.insert関数が の完了を待っているとき、この変数はどうなりますか? 私の理解では、「非ブロッキング」とは、IO 呼び出しが完了するのを待っているスレッドがなく、待機中にメモリが使用されていないことを意味します。varでは、格納されている値はどこにあるのでしょうか? 実行が再開されたときにどのようにアクセスできますか?

どんな助けでも大歓迎です!

4

1 に答える 1

6

のメモリは実行var中にまだ使用されていますが、関数自体は「凍結」されているため、他の関数を実行できます。Tornado のコルーチンは、Python ジェネレーターを使用して実装されます。これにより、関数の実行が発生したときに一時的に中断され、降伏点の後に (関数の状態が保持された状態で) 再び再開されます。ジェネレーターを導入した PEP での動作の説明は次のとおりです。insertgetyield

yield ステートメントが検出された場合、関数の状態は凍結され、値 [yielded] が .next() の呼び出し元に返されます。「凍結」とは、ローカル変数の現在のバインディング、命令ポインター、および内部評価スタックを含むすべてのローカル状態が保持されることを意味します。十分な情報が保存されるため、次に .next() が呼び出されたときに、関数は次のことができます。 yield ステートメントが単なる別の外部呼び出しであるかのように処理します。

ジェネレーターには、@gen.coroutineTornado のイベント ループに結び付ける魔法が組み込まれているため、呼び出しFutureによって返されたinsertがイベント ループに登録され、呼び出しが完了getしたときにジェネレーターを再起動できます。insert

于 2014-08-12T05:09:22.827 に答える