我从net的一些示例创建了一个webserver类。在捕获KeyboardInterrupt时,脚本结束,但是在KeyboardInterrupt之后不执行命令行。尝试的代码如下
import threading
import time
import signal
from http.server import BaseHTTPRequestHandler, HTTPServer
class WebServer(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.host = "localhost"
self.port = 8080
def run(self):
ws = HTTPServer((self.host, self.port), MyHander)
print("WebServer started at Port:",self.port)
try:
ws.serve_forever()
except KeyboardInterrupt:
pass
finally:
ws.server_close()
print("WebServer stopped")
class MyHander(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
self.wfile.write(bytes("<html><head><title>https://pythonbasics.org</title></head>", "utf-8"))
self.wfile.write(bytes("<p>Request: %s</p>" % self.path, "utf-8"))
self.wfile.write(bytes("<body>", "utf-8"))
self.wfile.write(bytes("<p>This is an example web server.</p>", "utf-8"))
self.wfile.write(bytes("</body></html>", "utf-8"))
webServer = WebServer()
webServer.start()
按下控制C时输出
WebServer started at Port:
>>> 8080
KeyboardInterrupt
>>>
我刚刚开始python编码。请帮助
最佳答案
键盘中断不会通过signal
包传递给主线程之外的线程。通常,这比您要实现的目标要复杂。如果要CTRL + C杀死webServer
线程,则需要做两件事。
首先确保您的主线程确实结束。即如果您的主线程用完了要执行的代码并等待其他线程完成,则您基本上处于死锁状态。使用while
循环很容易解决。
其次,处理主线程中的KeyboardInterrupt
并使用该信号关闭其他线程。同样,我们只是将其添加到while
循环中。
附带说明一下,似乎HTTPServer.shutdown
挂起(至少在Windows上),代码看起来正确,但是我认为这可能是继承名称处理问题。为了解决这个问题,我绕过了.shutdown
的调用,只是设置了手动终止服务器所需的属性。
import threading
import time
from http.server import BaseHTTPRequestHandler, HTTPServer
from time import sleep
class WebServer(threading.Thread):
def __init__(self):
super().__init__()
self.host = "localhost"
self.port = 8080
self.ws = HTTPServer((self.host, self.port), MyHandler)
def run(self):
print("WebServer started at Port:", self.port)
self.ws.serve_forever()
def shutdown(self):
# set the two flags needed to shutdown the HTTP server manually
self.ws._BaseServer__is_shut_down.set()
self.ws.__shutdown_request = True
print('Shutting down server.')
# call it anyway, for good measure...
self.ws.shutdown()
print('Closing server.')
self.ws.server_close()
print('Closing thread.')
self.join()
class MyHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
self.wfile.write(bytes("<html><head><title>Title</title></head>", "utf-8"))
self.wfile.write(bytes("<p>Request: %s</p>" % self.path, "utf-8"))
self.wfile.write(bytes("<body>", "utf-8"))
self.wfile.write(bytes("<p>This is an example web server.</p>", "utf-8"))
self.wfile.write(bytes("</body></html>", "utf-8"))
if __name__=='__main__':
webServer = WebServer()
webServer.start()
while True:
try:
sleep(1)
except KeyboardInterrupt:
print('Keyboard Interrupt sent.')
webServer.shutdown()
exit(0)
运行文件,访问http://localhost:8080/hello+world,然后发送CTRL + C如下所示:
(base) C:\Users\james>python serve.py
WebServer started at Port: 8080
127.0.0.1 - - [20/Nov/2019 12:53:16] "GET /hello+world HTTP/1.1" 200 -
Keyboard Interrupt sent.
Shutting down server.
Closing server.
Closing thread.
关于python - 在Windows上编码的python中未捕获KeyboardInterrupt,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58950268/