Python 在tornado web服务器中创建进程

Python 在tornado web服务器中创建进程,python,tornado,Python,Tornado,我有一个多进程tornado web服务器,我想创建另一个进程,在后台做一些事情 我有一个具有以下代码的服务器 start_background_process app = Application([<someurls>]) server = HTTPServer(app) server.bind(8888) server.start(4) # Forks multiple sub-processes IOLoop.current().start() def start_back

我有一个多进程tornado web服务器,我想创建另一个进程,在后台做一些事情

我有一个具有以下代码的服务器

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()
启动\u后台\u流程
app=应用程序([])
服务器=HTTPServer(应用程序)
服务器绑定(8888)
server.start(4)#分叉多个子进程
IOLoop.current().start()
def start_后台_进程():
进程=多进程。进程(目标=somefunc)
process.start()
一切都很顺利。 但是,当我尝试关闭服务器时(通过crtl c或发送信号) I get
AssertionError:只能加入子进程

我了解这个问题的原因: 当我使用multiprocess创建一个进程时,需要调用processjoin方法 是在“atexit”中注册的,因为tornado有一个简单的fork,所以它的所有孩子也调用我创建的进程的join方法,而不能,因为进程是他们的兄弟而不是他们的儿子? 那么,如何在tornado中正常打开一个进程呢?

“HTTPTserver start”使用os.fork来分叉4个子进程,正如它在其应用程序中所看到的那样

如果你想让你的方法被所有4个子进程执行,你必须在进程分叉后调用它

记住这一点,您的代码可以更改为如下所示:

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()
此外,为了在任何键盘中断期间保持程序的干净,请在服务器的实例化周围加上try…except子句,如下所示:

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()
“HttpTServerStart”使用os.fork来分叉4个子进程,正如它在其应用程序中所看到的那样

如果你想让你的方法被所有4个子进程执行,你必须在进程分叉后调用它

记住这一点,您的代码可以更改为如下所示:

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()
此外,为了在任何键盘中断期间保持程序的干净,请在服务器的实例化周围加上try…except子句,如下所示:

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()

谢谢你的回答。非常好:)谢谢你的回答,但是在你的回答中,它不会打开4个后台进程吗?我只想打开一个,这就是为什么我在开始之前就打开了。是的。在这种情况下,我会建议使用[Process Pool]()。您可以创建两个工作进程
pool=multiprocessing.pool(2)
,并使用第一个进程调用
somefunc
作为
池。应用异步(子进程上的方法())
,第二个进程调用tornado服务器的实例化。在键盘中断时,您可以使用
poll.terminate()
终止工作进程。我希望我能帮上忙。谢谢你的回答。非常好:)谢谢你的回答,但是在你的回答中,它不会打开4个后台进程吗?我只想打开一个,这就是为什么我在开始之前就打开了。是的。在这种情况下,我会建议使用[Process Pool]()。您可以创建两个工作进程
pool=multiprocessing.pool(2)
,并使用第一个进程调用
somefunc
作为
池。应用异步(子进程上的方法())
,第二个进程调用tornado服务器的实例化。在键盘中断时,您可以使用
poll.terminate()
终止工作进程。我希望我能帮上忙。