为什么 ctrl + c 不能在Windows上停止龙卷风服务器?
此代码未执行:print 'get sig:%d' % signum
import signal
import tornado
import tornado.web
import tornado.httpserver
class DefaultHandler(tornado.web.RequestHandler):
def get(self):
self.set_status(200, 'OK')
self.write('hello guest')
def post(self):
self.get()
class Receiver(object):
def __init__(self, address=None, port=8100, gzip=False):
if not address:
address = '0.0.0.0'
self.address = address
self.port = port
self.gzip = gzip
self.http_server = None
def start(self):
settings = dict(
)
application = tornado.web.Application([
(r"/", DefaultHandler),],
**settings)
self.http_server = tornado.httpserver.HTTPServer(application, decompress_request=self.gzip)
self.http_server.listen(self.port)
tornado.ioloop.IOLoop.instance().start()
def shutdown(self):
if self.http_server is not None:
self.http_server.stop()
tornado.ioloop.IOLoop.instance().stop()
if __name__ == '__main__':
receiver = Receiver(port=8901)
def sig_handler(signum, frame):
print 'get sig:%d' % signum
receiver.shutdown()
signal.signal(signal.SIGTERM, sig_handler)
signal.signal(signal.SIGINT, sig_handler)
receiver.start()
我的解决方案:
只有主线程可以处理信号,所以使用线程启动接收器并让主线程做一些假工作来保持活动
threading.Thread(target=receiver.start).start()
while 1:
try:
time.sleep(2)
except:
break
答案 0 :(得分:2)
信号处理程序是一种特殊的环境。你必须小心你在一个人做什么,因为你不知道被信号中断的功能的状态。在龙卷风中,只保证一个函数可以安全地从信号处理程序内部调用:IOLoop.add_callback_from_signal
。不要直接调用shutdown()
,而是使用add_callback_from_signal
来安排它:
def sig_handler(signum, frame):
IOLoop.current().add_callback_from_signal(receiver.shutdown)
答案 1 :(得分:0)
我在这里写了更详细的答案:https://stackoverflow.com/a/52941752/207661
简而言之,您需要为Windows手动安装Ctrl + C处理程序。
以下是方便的功能,这些功能将检测Windows并在控制台中安装Ctrl + C的自定义处理程序:
#win_ctrl_c.py
import sys
def handler(a,b=None):
sys.exit(1)
def install_handler():
if sys.platform == "win32":
import win32api
win32api.SetConsoleCtrlHandler(handler, True)
您可以在上面这样使用:
import threading
import time
import win_ctrl_c
# do something that will block
def work():
time.sleep(10000)
t = threading.Thread(target=work)
t.daemon = True
t.start()
#install handler
install_handler()
# now block
t.join()
#Ctrl+C works now!