16

Having this code:

def signal_handler(signal, frame):
    print("exiting")
    sys.exit(0)

if __name__ == "__main__":
    signal.signal(signal.SIGINT, signal_handler)

    threads_arr = []
    for i in list:
        t = threading.Thread(target=myFunc, args=(i))
        threads_arr.append(t)
        t.start()

How can I prevent this on pressing Ctrl+C

Exception ignored in: <module 'threading' from '/usr/lib/python3.4/threading.py'>
Traceback (most recent call last):
  File "/usr/lib/python3.4/threading.py", line 1294, in _shutdown
    t.join()
  File "/usr/lib/python3.4/threading.py", line 1060, in join
    self._wait_for_tstate_lock()
  File "/usr/lib/python3.4/threading.py", line 1076, in _wait_for_tstate_lock
    elif lock.acquire(block, timeout):
  File "./script.py", line 28, in signal_handler
    sys.exit(0)
SystemExit: 0

where line 28 is pointing at sys.exit(0)?

EDIT After trying to add t.join() (or t.join(1)) in the last for loop in main I get the same although I have to press Ctrl+C to get this error and exit the program.

Josh Correia
  • 3,807
  • 3
  • 33
  • 50
Patryk
  • 22,602
  • 44
  • 128
  • 244

1 Answers1

14

The problem is that you didn't set your threads to be daemons and you didn't join the threads, so when the main thread dies the rest keep running in the background.

If you edit your code to be as follows then it will work:

import signal
import threading
import sys

def signal_handler(signal, frame):
    print("exiting")
    sys.exit(0)

if __name__ == "__main__":
    signal.signal(signal.SIGINT, signal_handler)

    threads_arr = []
    for i in list:
        t = threading.Thread(target=myFunc, args=(i))
        threads_arr.append(t)
        t.daemon = True # die when the main thread dies
        t.start()
    for thr in threads_arr: # let them all start before joining
        thr.join()
Josh Correia
  • 3,807
  • 3
  • 33
  • 50
  • 1
    one could try exiting with os._exit(0) as well (your solution with sys.exit(0) didn't work for my case) – Qas Jul 19 '21 at 10:57