非同期イベント ループで適切に動作しないブロッキング タスクがある場合は、別のスレッドに配置する必要があります。
ブロッキング タスクの数に制限がない場合は、スレッド プールを使用します。
いずれにせよ、スレッド化されたタスクからの通知をブロックするラッパー非同期タスクが必要です。
これを行う最も簡単な方法は、 tornado-threadpool のようなビルド済みライブラリを使用することです。* 次に、次のようにします。
class LongHandler(tornado.web.RequestHandler):
@thread_pool.in_thread_pool
def long_time_function(self, callback):
time.sleep(5)
callback("foo")
自分でやりたい場合は、この Gistに必要な作業の例を示します。もちろん、さまざまな Tornado スレッドプール ライブラリのソース コードをサンプル コードとして使用することもできます。
Python GIL の制限に注意してください。バックグラウンド タスクが CPU バウンドの場合 (そして、numpy のように GIL をリリースする C 拡張機能ではなく、Python でほとんどの作業を行う場合)、それを別のプロセス。Tornado プロセス プール ライブラリを簡単に検索しても、適切なオプションはあまり見つかりませんでしたが、スレッド プール コードをプロセス プール コードに適合させることは、通常、Python では非常に簡単です。**
* そのライブラリを特に推奨しているわけではないことに注意してください。これは Google 検索で最初に出てきたものにすぎず、一見しただけで使用可能で正しいように見えます。
** 多くの場合concurrent.futures.ThreadPoolExecutor
、concurrent.futures.ProcessPoolExecutor
またはmultiprocessing.dummy.Pool
で置き換えるだけmultiprocessing.Pool
です。唯一の秘訣は、すべてのタスクの引数と戻り値が小さく、pickleable であることを確認することです。