我在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))
答案 0 :(得分:0)
线程与主进程共享相同的内存空间。所以技术上在主进程上执行ctrl-c应该释放线程内存。如果线程处于写入的中间,那么它可能是不安全的,但否则它应该没问题。否则,您可以使用python的signal库并创建一个信号处理程序来捕获SIGINT。