2015-12-21 9 views
5

私はFlaskウェブサーバーを使用して時間のかかる計算を行うインターフェイスを提供しています。パフォーマンスを向上させるために、私は非同期asyncioを呼び出すにはasyncio flask-aiohttpを使用した非同期サブプロセス

を使用して

  • 計算を実行してみましょう複数の同時計算に複数のCPUコアを使用できるようにnew subprocessとして計算を開始
    1. にしたいですFlask Iのコルーチンは、 flask-aiohttpを使い始めました。これは、例に示すように単純な遅延タスクでうまく動作しています。

      #!/usr/bin/env python3 
      # coding: utf-8 
      
      from flask import Flask 
      from flask.ext.aiohttp import AioHTTP, async 
      
      import asyncio 
      from asyncio.subprocess import PIPE 
      
      CALC_SCRIPT = './calc' 
      
      app = Flask(__name__) 
      aio = AioHTTP(app) 
      
      @app.route('/calc/<int:n>') 
      @async 
      def calc(n): 
          print('calc({}) called'.format(n)) 
          create = asyncio.create_subprocess_exec(CALC_SCRIPT, str(n), 
                    stdout=PIPE, stderr=PIPE) 
          print('create... ', end='') 
          process = yield from create 
          print('process created. {!r}, type={}'.format(process, 
                      type(process))) 
          yield from process.wait() 
          print('process finished.') 
      
          # yields (stdout, stderr) 
          result = '\n'.join(ch.decode().rstrip() for ch in 
               (yield from process.communicate()) if ch) 
          return result 
      
      if __name__ == '__main__': 
          aio.run(app, debug=True) 
      

      プロセスが作成されているが、決して返しません: しかし、私は、フラスコ内からの非同期サブプロセスを呼び出すことができない私は間違って何をやっている

      GET http://127.0.0.1:5000/calc/5 
      calc(5) called 
      creating... process created. <Process 5647>, 
          type=<class 'asyncio.subprocess.Process'> 
      

  • +0

    これですでに考えていると思いますが、* CALC_SCRIPT *は何をしますか?階乗などの単純な関数でテストしていますか? – wgwz

    +0

    これは役に立ちます:http://stackoverflow.com/questions/24541192/python-asyncio-subprocess-never-finishes – wgwz

    +0

    はい、 'CALC_SCRIPT'は[slow fibonacci script]です(https://gitlab.com/snippets/11746)をテスト目的で使用します。私はあなたがリンクした質問を見つけたが、私の[スタンドアロン版](https://gitlab.com/snippets/11748)はうまくいきました。 – Finwood

    答えて

    1

    理由:サブスレッドからのasyncioサブプロセスの実行には制限があります。asyncio docs Subprocess and threadsを参照してください。

    詳細:debug=Trueで、Flask-aiohttpは、Werkzeugのrun_with_reloaderで開始されたサブスレッドでリクエストを処理します。デバッグをオフにすると、コードが正しく実行されます。

    また、Flask-aiohttpはrun_with_reloaderを呼び出す前にasyncio.get_child_watcher()にコールを追加する必要があります。この呼び出しでは、コードはdebug=Trueであっても実行されます。

    関連する問題