如何停止Tornado Web服务器?

Ada*_*erg 32 python tornado

我一直在玩Tornado Web服务器,并且已经到了我想停止Web服务器的地步(例如在单元测试期间).Tornado网页上存在以下简单示例:

import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world")

application = tornado.web.Application([
    (r"/", MainHandler),
])

if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()
Run Code Online (Sandbox Code Playgroud)

一旦tornado.ioloop.IOLoop.instance().start()被调用,它就会阻塞程序(或当前线程).读取所述源代码IOLoop对象给出了文档在这个例子中stop功能:

To use asynchronous methods from otherwise-synchronous code (such as
unit tests), you can start and stop the event loop like this:
  ioloop = IOLoop()
  async_method(ioloop=ioloop, callback=ioloop.stop)
  ioloop.start()
ioloop.start() will return after async_method has run its callback,
whether that callback was invoked before or after ioloop.start.
Run Code Online (Sandbox Code Playgroud)

但是,我不知道如何将它集成到我的程序中.其实我有一个封装(有它自己的Web服务器类startstop函数),但只要我打电话开始时,程序(或测试)过程块会反正.

我试图在另一个进程中启动Web服务器(使用multiprocessing包).这是包装Web服务器的类:

class Server:
    def __init__(self, port=8888):
        self.application = tornado.web.Application([ (r"/", Handler) ])

        def server_thread(application, port):
            http_server = tornado.httpserver.HTTPServer(application)
            http_server.listen(port)
            tornado.ioloop.IOLoop.instance().start()

        self.process = Process(target=server_thread,
                               args=(self.application, port,))

    def start(self):
        self.process.start()

    def stop(self):
        ioloop = tornado.ioloop.IOLoop.instance()
        ioloop.add_callback(ioloop.stop)
Run Code Online (Sandbox Code Playgroud)

但是,停止似乎并没有完全停止Web服务器,因为它仍然在下一个测试中运行,即使使用此测试设置:

def setup_method(self, _function):
    self.server = Server()
    self.server.start()
    time.sleep(0.5)  # Wait for web server to start

def teardown_method(self, _function):
    self.kstore.stop()
    time.sleep(0.5)
Run Code Online (Sandbox Code Playgroud)

如何在Python程序中启动和停止Tornado Web服务器?

小智 27

我刚刚遇到这个并且自己发现了这个问题,并且使用来自此主题的信息提出了以下内容.我只是单独使用了我的工作站Tornado代码(从所有示例中复制)并将实际的起始代码移动到一个函数中.然后我将该函数称为线程线程.我的情况不同,因为线程调用是从我现有的代码完成的,我刚刚导入了startTornado和stopTornado例程.

上面的建议看起来效果很好,所以我想我会提供缺少的示例代码.我在Linux下在FC16系统上测试了这段代码(并修复了我的初始类型-o).

import tornado.ioloop, tornado.web

class Handler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world")

application = tornado.web.Application([ (r"/", Handler) ])

def startTornado():
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

def stopTornado():
    tornado.ioloop.IOLoop.instance().stop()

if __name__ == "__main__":
    import time, threading
    threading.Thread(target=startTornado).start()
    print "Your web server will self destruct in 2 minutes"
    time.sleep(120)
    stopTornado()
Run Code Online (Sandbox Code Playgroud)

希望这有助于下一个人.

  • 这不是线程安全的.可能会工作到一个星期五晚上,当你即将去五周假期. (25认同)

Zaa*_*Hai 18

这是如何从另一个线程停止Torando的解决方案.Schildmeijer提供了一个很好的提示,但我花了一段时间才真正想出最终的例子.

请看下面:

import threading
import tornado.ioloop
import tornado.web
import time


class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world!\n")

def start_tornado(*args, **kwargs):
    application = tornado.web.Application([
        (r"/", MainHandler),
    ])
    application.listen(8888)
    print "Starting Torando"
    tornado.ioloop.IOLoop.instance().start()
    print "Tornado finished"

def stop_tornado():
    ioloop = tornado.ioloop.IOLoop.instance()
    ioloop.add_callback(ioloop.stop)
    print "Asked Tornado to exit"

def main():

    t = threading.Thread(target=start_tornado)  
    t.start()

    time.sleep(5)

    stop_tornado()
    t.join()

if __name__ == "__main__":
    main()
Run Code Online (Sandbox Code Playgroud)

  • 这是否意在实际停止Web服务器?它似乎让港口开放. (7认同)
  • `ioloop.add_callback(lambda x: x.stop(), ioloop)` 或者更简单地说:`ioloop.add_callback(ioloop.stop)` (2认同)

Ale*_*era 9

如果你不想打扰线程,你可以捕获键盘中断信号:

try:
    tornado.ioloop.IOLoop.instance().start()
# signal : CTRL + BREAK on windows or CTRL + C on linux
except KeyboardInterrupt:
    tornado.ioloop.IOLoop.instance().stop()
Run Code Online (Sandbox Code Playgroud)

  • 在Python 2.7/Windows 10下:这很有用:`CTRL-BREAK`确实让我脱离了`tornado.ioloop`.但是,它肯定不会引发一个`KeyboardInterrupt`.事实上,在"CTRL-BREAK"之后没有达成任何陈述.无论它做什么,它都在努力和快速地杀死这个过程. (2认同)