Stop threads gracefully

Viewed 2079

I am close to finishing my program, and I wanted to fix this error before making my first ever release.

This is the error I'm talking about:

Exception ignored in: <module 'threading' from '/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py'>
Traceback (most recent call last):
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 1281, in _shutdown
    t.join()
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 1032, in join
    self._wait_for_tstate_lock()
  File "/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 1048, in _wait_for_tstate_lock
    elif lock.acquire(block, timeout):
KeyboardInterrupt

I start the threads like this:

def init(self):

    new_post_stream_thread = threading.Thread(target=self.new_post_stream)
    process_posts = threading.Thread(target=self.process_posts)
    print('\nStarting threads...')
    print('- - - - - - - - - -\n')
    new_post_stream_thread.start()
    process_posts.start()

And that's basically it. How would I catch this exception? I tried with a try except already but it doesn't catch anything.

Here's the MCVE:

import threading
import time

class MCVE:

    def __init__(self):

        self.list_1 = []

        self.init()

    def thread_1(self):

        while True:
            self.list_1.append('whatever')
            time.sleep(5)

    def thread_2(self):

        while True:
            for id, entry in enumerate(self.list_1):
                print('ID {} | entry: {}'.format(id, entry))
            time.sleep(10)

    def init(self):
        thread_1 = threading.Thread(target=self.thread_1)
        thread_2 = threading.Thread(target=self.thread_2)
        print('\nStarting threads...')
        print('- - - - - - - - - -\n')
        thread_1.start()
        thread_2.start()


def main():

    example = MCVE()

if __name__ == "__main__":
    main()
2 Answers

You didn't provide a reproducible example, but this successfully stops the program without raising an uncaught exception:

def foo(n):
    import time
    try:
        for i in range(n):
            time.sleep(i)
    except KeyboardInterrupt:
        print("Clean exit....")
        return
Related