Python KeyboardInterrupt in Multithreading

爱⌒轻易说出口 提交于 2019-12-08 03:22:29

问题


Can anyone please tell me why the KeyboardInterrupt is not working here? I need to end both of the threads by the press of CTRL+C. The two threads - Timer thread and Web server thread. Here is the code -

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

回答1:


First, your instance myThread in created with error, must be stopper=stopper (keyword arg is expected). Second, code has error, main thread does not wait server thread but immediately go to join()s. So, except never happens - nothing will be printed. And main bug is in join(). Join in Python is not interruptable by signals. So, you must write own join function, which will call original join() with timeout (for example, 1 second) but in the infinitive loop. Better is to make join with little timeout and next - sleep() - sleep is interruptable. Both in the loop.




回答2:


Try to print something next of except KeyboardInterrupt, before to call join()s, bcz joins are waiting for threads to complete.



来源:https://stackoverflow.com/questions/43721150/python-keyboardinterrupt-in-multithreading

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!