2016-12-07 2 views
0

Ich habe einen Tornado-Webserver mit mehreren Prozessoren und ich möchte einen anderen Prozess erstellen, der einige Dinge im Hintergrund tun wird.Erstellen Sie einen Prozess in Tornado-Webserver

Ich habe einen Server mit dem Code zu folgenden

start_background_process 
app = Application([<someurls>]) 
server = HTTPServer(app) 
server.bind(8888) 
server.start(4) # Forks multiple sub-processes 
IOLoop.current().start() 

def start_background_process(): 
    process = multiprocessing.Process(target=somefunc) 
    process.start() 

und alles funktioniert super. Allerdings, wenn ich versuche, den Server (durch crtl c oder Signal senden) zu schließen ich AssertionError: can only join a child process

ich die Ursache dieses Problems zu verstehen: , wenn ich einen Prozess mit Multi-Prozess einen Aufruf für den Prozess Methode beitreten schaffen registriert in "atexit" und weil Tornado eine einfache Gabel alle seine Kinder auch die Join-Methode des Prozesses, den ich erstellt habe, und die können nicht seit dem Prozess ist ihr Bruder und nicht ihr Sohn? Wie kann ich einen Prozess normalerweise im Tornado öffnen?

Antwort

2

HTTPTserver starten“ verwendet os.fork die 4 Teilprozesse gabeln, wie es in seiner source code zu sehen ist.

Wenn Sie möchten, dass Ihre Methode von allen 4 Teilprozessen ausgeführt wird, müssen Sie sie aufrufen, nachdem die Prozesse verzweigt wurden.

Nachdem in diesem Sinne kann der Code geändert werden, wie weiter unten zu sehen:

import multiprocessing 
import tornado.web 
from tornado.httpserver import HTTPServer 
from tornado.ioloop import IOLoop 

# A simple external handler as an example for completion 
from handlers.index import IndexHandler 


def method_on_sub_process(): 
    print("Executing in sub-process") 


def start_background_process(): 
    process = multiprocessing.Process(target=method_on_sub_process) 
    process.start() 


def main(): 
    app = tornado.web.Application([(r"/", IndexHandler)]) 
    server = HTTPServer(app) 
    server.bind(8888) 
    server.start(4) 
    start_background_process() 
    IOLoop.current().start() 


if __name__ == "__main__": 
    main() 

Darüber hinaus das Verhalten Ihres Programms sauber während einer Tastatur Unterbrechung zu halten, umgeben die Instanziierung der Sever durch einen versuchen. .. except Klausel wie folgt:

def main(): 
    try: 
     app = tornado.web.Application([(r"/", IndexHandler)]) 
     server = HTTPServer(app) 
     server.bind(8888) 
     server.start(4) 
     start_background_process() 
     IOLoop.current().start() 
    except KeyboardInterrupt: 
     IOLoop.instance().stop() 
+0

Danke für Ihre Antwort. Wirklich gut :) –

+0

Danke für die Antwort, aber in Ihrer Antwort wird es nicht 4 Hintergrundprozesse öffnen? Ich möchte nur einen öffnen und das ist, warum ich es vor dem Start tat – kill129

+0

Ja, das ist richtig. In diesem Fall hätte ich die Verwendung von [Process Pool] (https://docs.python.org/2/library/multiprocessing.html?highlight=pool#module-multiprocessing.pool) vorgeschlagen. Sie können zwei Worker-Prozesse 'pool = multiprocessing.Pool (2)' erstellen und die erste verwenden, um 'somefunc' als' pool.apply_async (method_on_sub_process,()) 'und die zweite Instanz die Instanziierung Ihres Tornado-Servers aufzurufen. Bei Interrupt auf der Tastatur können Sie die Worker-Prozesse mit 'poll.terminate()' beenden. Ich hoffe, ich war etwas Hilfe. – afxentios

Verwandte Themen