2017-05-26 12 views
1

このハンドラを単純なTornadoアプリケーションで実行し、curlで2つの要求を行うと、並列処理は実行されません。 「1 1 2 2 3 3 4 4 5 5」と印刷したいときは「1 2 3 4 5 1 2 3 4 5」を印刷します。なぜ、time.sleepがトルネードコルーチンで並行して実行されないのですか?

class SleepHandler(RequestHandler): 
    def get(self): 
     for i in range(5): 
      print(i) 
      time.sleep(1) 

私は間違っていますか?それは他のハンドラが実行できるように、コントロールがIOLoopに復帰することはできません:

答えて

3

この理由はtime.sleepが機能をブロックであるということです。

もちろん、time.sleepは、これらの例では単なるプレースホルダです。そのポイントは、ハンドラ内の何かが遅くなるとどうなるかを示すことです。実際のコードが何をしていても、並行性のブロッキングコードを実現するには、コードを非ブロッキングの同等物に置き換える必要があります。これは、3つのいずれかを意味します

  • はコルーチン優しい同等を探します。 time.sleepの場合は、代わりにtornado.gen.sleepを使用してください。

    class CoroutineSleepHandler(RequestHandler): 
        @gen.coroutine 
        def get(self): 
         for i in range(5): 
          print(i) 
          yield gen.sleep(1) 
    

    このオプションを使用すると、通常は最適な方法です。便利な非同期ライブラリへのリンクについては、Tornado wikiを参照してください。

  • をコールバックに基づいて検索します。コールバックベースのライブラリは、最初のオプションと同様に、多くのタスクで使用できますが、コルーチン用に設計されたライブラリよりも少し複雑です。これらは通常のアダプタとしてtornado.gen.Taskで使用されています

    class CoroutineTimeoutHandler(RequestHandler): 
        @gen.coroutine 
        def get(self): 
         io_loop = IOLoop.current() 
         for i in range(5): 
          print(i) 
          yield gen.Task(io_loop.add_timeout, io_loop.time() + 1) 
    

    ここでも、Tornado wikiは、適切なライブラリを見つけるために役立ちます。

  • ブロッキングコードを別のスレッドで実行します。非同期ライブラリが利用できない場合、concurrent.futures.ThreadPoolExecutorを使用して、別のスレッドでブロッキングコードを実行できます。

    executor = concurrent.futures.ThreadPoolExecutor(8) 
    
    class ThreadPoolHandler(RequestHandler): 
        @gen.coroutine 
        def get(self): 
         for i in range(5): 
          print(i) 
          yield executor.submit(time.sleep, 1) 
    

    ブロッキングおよび非同期機能の詳細についてはトルネードのユーザーズガイドのAsynchronous I/O chapterを参照してください。これは、非同期の相手が存在するかどうかを任意のブロッキング機能のために使用することができるユニバーサルソリューションです。

+0

私はあなたがこの回答を貼り付けることができたらいいですよ。 –

+0

それは考えです。これは[the tornado faq](http://www.tornadoweb.org/en/stable/faq.html#why-isn-t-this-example-with-time-sleep-running-in-parallel)からコピーされています。これを求める他のすべての質問は、この質問の重複として閉じられる可能性があります。 –

関連する問題