2015-12-21 2 views
5

Ich verwende einen Flask Webserver, um eine Schnittstelle zu einer zeitaufwendigen Berechnung bereitzustellen. mehrere CPU-Kerne für mehrere gleichzeitige Berechnungen asynchroner Subprozess mit flask-aiohttp

  • lassen die Berechnungen zur Leistungserhöhung möchte ich

    1. die Berechnung als new subprocess beginnen zu können, verwenden laufen asynchron asyncio mit

    asyncio nennen Koroutinen von Flask Ich fing an, flask-aiohttp zu verwenden, das für einfache Verzögerungsaufgaben gut arbeitet, wie in den Beispielen gezeigt. Allerdings habe ich nicht die asynchrone subprocess von innen Flask nennen:

    #!/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) 
    

    Der Prozess erstellt wird, aber nie zurückgibt:

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

    Was mache ich falsch?

  • +0

    Ich bin mir sicher, dass du schon darüber nachgedacht hast, aber was macht * CALC_SCRIPT *? Testen Sie mit einer einfachen Funktion wie einer Fakultät oder etwas? – wgwz

    +0

    Dies könnte hilfreich sein: http://StackOverflow.com/Questions/24541192/Python-Asyncio-SubProcess-Never-Finishes – wgwz

    +0

    Ja, 'CALC_SCRIPT' ist ein [langsames Fibonacci-Skript] (https://gitlab.com/snippets/11746) zu Testzwecken. Ich bin über die Frage gestolpert, mit der Sie verknüpft sind, aber meine [Standalone-Version] (https://gitlab.com/snippets/11748) funktioniert gut. – Finwood

    Antwort

    1

    Grund: Das Ausführen von asyncio-Subprozessen aus Sub-Threads hat Limits, siehe ascio docs Subprocess and threads.

    Detail: mit debug=True, Flask-aiohttp Handle Anfragen in einem Unter-Thread von Werkzeug run_with_reloader gestartet. Deaktivieren Sie das Debuggen, und Ihr Code wird ordnungsgemäß ausgeführt.

    Alternativ zu den oben genannten Dokumenten sollte Flask-aiohttp einen Anruf an asyncio.get_child_watcher() direkt vor dem Anruf run_with_reloader hinzufügen. Mit diesem Aufruf wird Ihr Code sogar mit debug=True ausgeführt.