2013-06-14 30 views
12

Tôi mới sử dụng máy chủ web lốc xoáy. Khi tôi bắt đầu máy chủ web cơn lốc xoáy bằng cách sử dụng python main_tornado.py Nó đang hoạt động. Vui lòng xem mã bên dưới.Làm thế nào để dừng máy chủ web lốc xoáy bằng ctrl + c?

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

Khi tôi dừng máy chủ bằng CTRL + C, lỗi này đã xảy ra lỗi sau.

^CTraceback (most recent call last): 
    File "main_tornado.py", line 19, in <module> 
    tornado.ioloop.IOLoop.instance().start() 
    File "/home/nyros/Desktop/NewWeb/venv/lib/python3.2/site-packages/tornado/ioloop.py", line 301, in start 
    event_pairs = self._impl.poll(poll_timeout) 
KeyboardInterrupt 

Vui lòng giải quyết sự cố của tôi. Thanks ..

+0

thể trùng lặp của [Làm thế nào để ngăn chặn máy chủ web Tornado?] (Http://stackoverflow.com/questions/5375220/how-do-i-stop-tornado-web-server) – Blender

+0

Tại sao điều này vấn đề? –

Trả lời

21

Bạn có thể dừng vòng lặp chính Tornado với tornado.ioloop.IOLoop.instance().stop(). Để có phương pháp này được gọi là sau khi tín hiệu đi qua với Ctrl + C bạn có thể kiểm tra định kỳ cờ toàn cầu để kiểm tra nếu vòng lặp chính nên kết thúc và đăng ký handler cho tín hiệu SIGINT mà sẽ thay đổi giá trị của lá cờ này:

#!/usr/bin/python 
# -*- coding: utf-8 -*- 

import tornado.ioloop 
import tornado.web 
import signal 
import logging 
from tornado.options import options 

is_closing = False 

def signal_handler(signum, frame): 
    global is_closing 
    logging.info('exiting...') 
    is_closing = True 

def try_exit(): 
    global is_closing 
    if is_closing: 
     # clean up here 
     tornado.ioloop.IOLoop.instance().stop() 
     logging.info('exit success') 

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

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

if __name__ == "__main__": 
    tornado.options.parse_command_line() 
    signal.signal(signal.SIGINT, signal_handler) 
    application.listen(8888) 
    tornado.ioloop.PeriodicCallback(try_exit, 100).start() 
    tornado.ioloop.IOLoop.instance().start() 

Output:

$ python test.py 
[I 130614 11:19:19 web:1514] 200 GET/(127.0.0.1) 0.56ms 
^C[I 130614 11:19:21 test:14] exiting... 
[I 130614 11:19:21 test:22] exit success 

CẬP NHẬT

Tôi vừa thấy trong câu hỏi Tornado long polling requests giải pháp đơn giản này:

try: 
    tornado.ioloop.IOLoop.instance().start() 
except KeyboardInterrupt: 
    tornado.ioloop.IOLoop.instance().stop() 

Rõ ràng, đây là một cách kém an toàn.

+0

Cảm ơn bạn đã trả lời. Mã của bạn là hoàn hảo. Tôi đang sử dụng cơn lốc xoáy httpserver.Khi tôi nhấn ctrl + c thì mất nhiều thời gian để tiêu diệt máy chủ. Bất kỳ ý tưởng nào. – dhana

+0

Bạn có thể có một số tác vụ chặn phải được kết thúc trước khi 'try_exit()' gọi lại được gọi. Bạn có thể thử sử dụng 'tornado.ioloop.IOLoop.instance(). Stop()' trực tiếp trong trình xử lý tín hiệu nhưng dường như nó ít an toàn hơn đối với tôi. Nếu bạn muốn phá vỡ vòng lặp vô hạn một cách tàn nhẫn ở giữa quá trình xử lý, sẽ rất khó để tránh các thông báo lỗi. – Nykakin

+0

Giải pháp gốc (xử lý tín hiệu.SIGINT) hoạt động tốt cho tôi trên Windows, nhưng "UPDATE" cho câu trả lời của bạn (chỉ đơn giản là bắt KeyboardInterrupt) thì không. Ctrl + C trên Windows sẽ không tạo ra KeyboardInterrupt và một số người (như tôi, với một bàn phím nhỏ gọn) không có CTRL + Pause Break trên bàn phím của họ. –

2

Mã là OK. CTRL + C tạo KeyboardInterrupt. Để dừng máy chủ, bạn có thể sử dụng CTRL + Pause Break (trên cửa sổ) thay vì CTRL + C. Trên linux CTRL + C cũng tạo ra KeyboardInterrupt. Nếu bạn sẽ sử dụng chương trình CTRL + Z sẽ dừng nhưng cổng bị bận.

+0

Khi bạn nói ''CTRL +' thay vì' CTRL + C' ', bạn có thực sự có nghĩa là Control và phím' plus 'không? Bởi vì điều đó không có gì cho tôi – puk

+0

Xin lỗi, tôi đã biên tập các tuyên bố của tôi ở đó. –

+1

'CTRL + Z' sẽ không dừng nó, nhưng chỉ đơn giản là di chuyển quá trình vào nền. – WhyNotHugo

4

Bạn có thể chỉ cần dừng vòng lặp Tornado từ trình xử lý tín hiệu. Nó sẽ an toàn nhờ phương thức add_callback_from_signal(), vòng lặp sự kiện sẽ thoát ra độc đáo, hoàn thành bất kỳ nhiệm vụ chạy đồng thời nào.

import tornado.ioloop 
import tornado.web 
import signal 

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

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

def sig_exit(signum, frame): 
    tornado.ioloop.IOLoop.instance().add_callback_from_signal(do_stop) 

def do_stop(signum, frame): 
    tornado.ioloop.IOLoop.instance().stop() 

if __name__ == "__main__": 
    application.listen(8888) 
    signal.signal(signal.SIGINT, sig_exit) 
    tornado.ioloop.IOLoop.instance().start() 
+3

điều này thực sự là câu trả lời được chấp nhận thay vì ô nhiễm toàn cầu ở khắp mọi nơi. – cowbert

+0

bất kỳ lý do nào không sử dụng 'lambda' thay vì xác định rõ ràng' do_stop'? – cowbert

+0

do_stop() có thể được gọi từ những nơi khác. Nhưng quả thực, nó có thể là lambda. –

Các vấn đề liên quan