I want to exit the crawler script which is using threading, but it doesn't detect Ctrl c. I tried to try and except inside the main thread and in newly created threads, but it doesn't raise the exception, signal in main thread, but main thread isn't active, and it doesn't detect it.
import threading
import signal
class Crawler(threading.Thread):
def __init__(self, num):
threading.Thread.__init__(self)
# Other stuff
def run(self, ):
try:
self.crawl()
except KeyboardInterrupt:
self.exit()
def crawl(self):
for url in self.links_list:
try:
# Getting the website and all links on it and adding it to links_list
pass
except (KeyboardInterrupt, SystemExit):
self.exit()
except AssertionError:
self.exit()
def exit(self):
# Saving progress
raise SystemExit()
def handler(signum, frame):
exit()
if __name__ == "__main__":
signal.signal(signal.SIGINT, handler)
for i in range(8):
crawler = Crawler(i)
crawler.start()
CodePudding user response:
Instead of trying to do stuff with signals, use a threading.Event()
to signal all of the other threads to stop:
import threading
import time
stop_signal = threading.Event()
class Crawler(threading.Thread):
def __init__(self, num):
threading.Thread.__init__(self)
# Other stuff
def run(self):
try:
for url in self.links_list:
# Between every url, see if we should stop
if stop_signal.is_set():
break
# Getting the website and all links on it and adding it to links_list
finally:
self.save_progress()
def save_progress(self):
pass
def main():
crawlers = [Crawler(x) for x in range(8)]
for crawler in crawlers:
crawler.start()
# Do nothing for a whole long while in the main loop
# (you could exit the loop when all jobs are done, though)
while True:
try:
time.sleep(1)
except KeyboardInterrupt:
stop_signal.set()
break
for crawler in crawlers:
crawler.join()
if __name__ == "__main__":
main()