Why sys.exit() dose not shutdown python when there are backgroud threads?

import sys
import time
from threading import Thread


def run_forever():
    while True:
        time.sleep(1)
        print('running')


if __name__ == '__main__':
    t = Thread(target=run_forever)
    t.start()
    sys.exit()

It seems sys.exit can’t shutdown the program if I still have any background threads. In this case, how can I gracefully close this program (especially when I can’t see all the background threads)?

EDIT

I know it’s better to keep track of all the background threads. But in this use case I know it’s safe to kill them all at once. I just can’t find a way to simply close the program.

Answer

There’s no real reason why this happens other than sys.exit is designed to only end the thread it is called from, as you’ve demonstrated here. There are two options that you can use to get the behavior you’re expecting.

  1. Use daemon threads. Daemon threads will exit if their parent exits. You can make your code use daemon threads like this:
if __name__ == '__main__':
    t = Thread(target=run_forever)
    t.daemon = True
    t.start()
    sys.exit()
  1. Use os._exit This will end your program similar to how I imagine you think sys.exit() behaves. This is more of a brute force method and is probably not a good idea, but is possible.

I would recommend using daemon threads unless you absolutely cannot. (i.e. you want to sometimes end just the main thread while the other continue, and sometimes end all of them at once.) More information on daemon threads: https://www.geeksforgeeks.org/python-daemon-threads/