如何在设置信号处理程序时防止出现:<module 'threading' from ...>中忽略异常?

16 投票
1 回答
22788 浏览
提问于 2025-04-18 09:28

有这样一段代码:

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()

我该如何在按下 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

第28行指向的是 sys.exit(0)

编辑 在尝试在 main 中的最后一个 for 循环里添加 t.join()(或者 t.join(1))后,我发现结果还是一样,虽然我必须按 Ctrl+C 才会出现这个错误并退出程序。

1 个回答

15

问题在于你没有把你的线程设置为守护线程,也没有把线程合并到主线程中。所以当主线程结束时,其他线程仍然在后台继续运行。

如果你把代码修改成下面这样,它就能正常工作了:

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()

撰写回答