0

私はPythonでポートスキャンプログラムを作成していますが、すべてうまくいきますが、プログラムを終了するcrtl + c割り込み機能を実装したいのですが、メインプログラムを停止します。 ctrl + cキーを使ってプログラムを完全に終了するには?Pythonでキーボード割り込みを実装する方法

class StatusChecker(threading.Thread): 
    """ 
    The thread that will check HTTP statuses. 
    """ 

    #: The queue of urls 
    url_queue = None 

    #: The queue our results will go into 
    result_queue = None 

    #: An event that tells the thread to stop 
    stopper = None 

    def __init__(self, url_queue, result_queue, stopper): 
     super().__init__() 
     self.url_queue = url_queue 
     self.result_queue = result_queue 
     self.stopper = stopper 

    def run(self): 
     print_lock = threading.Lock() 
     while not self.stopper.is_set(): 
      try: 
       # this will throw queue.Empty immediately if there's 
       # no tasks left 
       to_check = self.url_queue.get_nowait() 
      except queue.Empty: 
       break # empty queue, we're done! 
      else: 
       with print_lock: 
        print(to_check,' ') 
       self.url_queue.task_done() # the the queue we're done 


class SignalHandler: 
    """ 
    The object that will handle signals and stop the worker threads. 
    """ 

    #: The stop event that's shared by this handler and threads. 
    stopper = None 

    #: The pool of worker threads 
    workers = None 

    def __init__(self, stopper, workers): 
     self.stopper = stopper 
     self.workers = workers 

    def __call__(self, signum, frame): 
     """ 
     This will be called by the python signal module 

     https://docs.python.org/3/library/signal.html#signal.signal 
     """ 
     self.stopper.set() 

     for worker in self.workers: 
      worker.join() 

     sys.exit(0) 


if __name__ == '__main__': 
    # all the variables we'll need 
    num_workers = 2 
    stopper = threading.Event() 
    result_queue = queue.Queue() 
    url_queue = queue.Queue() 

    # populate our work queue 
    for i in range(65535): 
     url_queue.put(i) 

    # we need to keep track of the workers but not start them yet 
    workers = [StatusChecker(url_queue, result_queue, stopper) for i in range(num_workers)] 

    # create our signal handler and connect it 
    #handler = SignalHandler(stopper, workers) 
    #signal.signal(signal.SIGINT, handler) 

    # start the threads! 
    for i, worker in enumerate(workers): 
     print('Starting worker {}'.format(i)) 
     worker.daemon = True 
     worker.start() 

    # wait for the queue to empty 
    try: 
     while threading.active_count() > 0: 
      time.sleep(0.1) 
    except: 
     sys.exit(0) 
    while not result_queue.empty(): 
     url, status = result_queue.get_nowait() 
     print('{} - {}'.format(url, status)) 

答えて

0

スレッドは、メインプロセスと同じメモリスペースを共有します。だから技術的には、メインプロセスでctrl-cを実行すると、スレッドメモリの割り当てを解除する必要があります。スレッドが書き込みの途中にある場合、安全ではない可能性がありますが、それ以外の場合はOKです。それ以外の場合は、Pythonのsignalライブラリを使用して、シグナルハンドラを作成してSIGINTをトラップすることができます。

関連する問題