谁能告诉我为什么键盘中断在这里不起作用?我需要通过按 CTRL+C 结束两个线程。两个线程 - 计时器线程和 Web 服务器线程。这是代码 -
import threading
import thread
import time
import urllib2
import httplib
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
from SocketServer import ThreadingMixIn
import Queue
import signal
import sys
q = Queue.Queue()
j = Queue.Queue()
h = "threading working!"
class SignalHandler:
stopper = None
def __init__(self,stopper):
self.stopper = stopper
def __call__(self, signum, frame):
self.stopper.set()
sys.exit(0)
#Timer Thread
class myThread(threading.Thread):
stopper = None
def __init__(self, **kwargs):
self.req = []
self.stopper = stopper
for k, v in kwargs.iteritems():
setattr(self, k, v)
threading.Thread.__init__(self)
def run(self):
while not self.stopper.is_set():
while self.go:
try:
while True:
r = q.get_nowait()
self.req.append(r)
except Queue.Empty, e:
pass
t = threading.Timer(1,self.hello, [h])
t.start()
time.sleep(1)
def hello(self, s):
print s
while self.req:
r = self.req.pop()
print "Client Request >>>>>>>", r
thread_id = str(threading.currentThread())
j.put(thread_id)
def stop(self):
print "Stopping thread.."
self.go = False
try:
while True:
q.get_nowait()
q.task_done()
except Queue.Empty, e:
pass
#Webserver thread
class Handler(BaseHTTPRequestHandler):
def do_HEAD(self):
self.send_response(200)
self.send_header("Content type", "text/html")
self.end_headers()
def do_GET(self):
self.do_HEAD()
req = (self.path, self.client_address, self.command,)
q.put(req)
self.wfile.write("Thread Info: ")
self.wfile.write(j.get())
return
class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
"""Handle requests in a separate thread."""
#main
if __name__ == '__main__':
stopper = threading.Event()
handler = SignalHandler(stopper)
signal.signal(signal.SIGINT, handler)
server = ThreadedHTTPServer(('localhost', 8080), Handler)
try:
timer_thread = myThread(stopper,go=True)
timer_thread.start()
server_thread = threading.Thread(target=server.serve_forever)
server_thread.daemon = True
server_thread.start()
print 'Starting server, use <Ctrl-C> to stop'
except KeyboardInterrupt, e:
print "Interrupted"
q.join()
j.join()
timer_thread.stop()
timer_thread.join()
首先,您的实例myThread
创建错误,必须stopper=stopper
(关键字 arg 是必需的)。其次,代码有错误,主线程不等待服务器线程,而是立即转到join()
。所以,except
永远不会发生 - 什么都不会打印。主要错误在join()
.在 Python 中加入是不能被信号中断的。因此,您必须编写自己的 join 函数,该函数将在不定式循环中调用超时(例如 1 秒)的原始join()
。更好的是使加入时几乎没有超时,下一个 -sleep()
- 睡眠是可中断的。两者都在循环中。
尝试在except KeyboardInterrupt
旁边打印一些内容,在调用join()
s 之前,bcz 连接正在等待线程完成。