我正在用python编写一个端口扫描程序,一切正常,但我想实现crtl+c中断函数来终止程序它停止主程序但仍有线程在运行。如何使用 ctrl+c 键完全终止程序?
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))