Keyboardinterrupt doesn't stop threading to keep on going in python

1.5k Views Asked by At

This code is running fine, my only problem is when I need to stop my code, I enter ctrl+c despite giving :

for thread in threads:
    thread.alive = False
    thread.join()
    sys.exit(e)

In the code, the thread keeps on running, say the thread has to download, even after keyinterrupt it keeps on download. What can I do to exit the code gracefully?

This the complete code :

 try:
    threads = []
    while len(list1) != 0:
        while len(threads) != 4:
            time.sleep(1)
            item = list1.pop(0)
            thread = threading.Thread(target=func, args=(item, ))
            threads.append(thread)
            thread.start()
        for thread in threads:
            thread.join()
        for thread in threads:
            if not thread.is_alive():
                # get results from thread
                threads.remove(thread)
        if len(list1) == 0:
            logging.error("Nothing")
            sys.exit(1)
except KeyboardInterrupt as e:
    logging.error("Keyboard Interruption, code exiting!!")
    list1.append(item)
    logging.info(f'{item} Adding back to the list')
    # whenever there is a keyboard interrupt kill all the threads
    for thread in threads:
        thread.alive = False
        thread.join()
        sys.exit(e)
except Exception as e:
    logging.exception(f'Failed to initiate the threads : {e}')
    sys.exit(1)
2

There are 2 best solutions below

2
On

Setting thread.alive = False won't do anything unless the thread actually cares about the flag. If you want to terminate gracefully, you need to modify your target func to periodically check the value of alive and stop running if it's False.

Alternatively, if you don't care about graceful shutdowns and just want all threads to exit when the main thread does, you can add daemon=True to the Thread constructor when you create them.

3
On

I think you need is to find a way to kill a thread. This is not usually advisable, especially when the thread is reading/writing to a file for example, or when the thread is handling other threads. I'd recommend reading this post for more details.

You could create a custom thread wrapper to handle stopping threads safely, or if you use the multiprocessing library, you can call process.terminate().