Equivalent of thread.interrupt_main() in Python 3

Viewed 6643

In Python 2 there is a function thread.interrupt_main(), which raises a KeyboardInterrupt exception in the main thread when called from a subthread.

This is also available through _thread.interrupt_main() in Python 3, but it's a low-level "support module", mostly for use within other standard modules.

What is the modern way of doing this in Python 3, presumably through the threading module, if there is one?

3 Answers

Well raising an exception manually is kinda low-level, so if you think you have to do that just use _thread.interrupt_main() since that's the equivalent you asked for (threading module itself doesn't provide this).

It could be that there is a more elegant way to achieve your ultimate goal, though. Maybe setting and checking a flag would be already enough or using a threading.Event like @RFmyD already suggested, or using message passing over a queue.Queue. It depends on your specific setup.

You might want to look into the threading.Event module.

If you need a way for a thread to stop execution of the whole program, this is how I did it with a threading.Event:

def start():
    """
    This runs in the main thread and starts a sub thread
    """
    
    stop_event = threading.Event()
    check_stop_thread = threading.Thread(
        target=check_stop_signal, args=(stop_event), daemon=True
    )
    check_stop_thread.start()
    # If check_stop_thread sets the check_stop_signal, sys.exit() is executed here in the main thread.
    # Since the sub thread is a daemon, it will be terminated as well.
    stop_event.wait()
    logging.debug("Threading stop event set, calling sys.exit()...")
    sys.exit()




def check_stop_signal(stop_event):
    """
    Checks continuously (every 0.1 s) if a "stop" flag has been set in the database.
    Needs to run in its own thread.
    """
    while True:
        if io.check_stop():
            logger.info("Program was aborted by user.")
            logging.debug("Setting threading stop event...")
            stop_event.set()
            break
        sleep(0.1)
Related