Ctrl+c 不停止 Windows + python3.7 中的线程

Posted

技术标签:

【中文标题】Ctrl+c 不停止 Windows + python3.7 中的线程【英文标题】:Ctrl+c not stopping a Thread in Windows + python3.7 【发布时间】:2021-12-23 11:15:32 【问题描述】:

我正在尝试这个带有 while 循环的简单线程。当我在 while 循环中时,Ctrl+C 无法停止我的程序。一旦我在 while 循环之后做其他事情,脚本就会按预期停止。我该怎么做才能让我的脚本在 while 循环中和之后被优雅地杀死? (编辑:这似乎是 Windows 独有的问题,ios 和 Ubuntu 似乎可以满足我的要求)

import time, threading


class MainClass(threading.Thread):

    def __init__(self):
        super().__init__()

    def run(self):
        while True:
            time.sleep(1)
            print("Looping")


# Script entry point
if __name__ == '__main__':

    a = MainClass()
    a.daemon = True
    a.start()
    a.join()

【问题讨论】:

什么 Python3 版本?什么操作系统?如果我运行您的示例,它会不断打印“循环”,直到我按下 Ctrl+C。然后它转储堆栈(KeyboardInterrupt)并退出。我在 MacOS 上运行 Python 3.8.9。 另外,“按预期停止”和“优雅地杀死”是什么意思?有人可能会说转储堆栈并不“优雅”。 我在 Windows 上运行 python 3.7.5(在虚拟环境中,但在它之外做同样的事情)。对我来说,它只是一直打印“循环”,直到我用任务管理器杀死它,因为 Ctrl+C 根本没有任何效果。 “优雅地”我的意思是不要留下任何僵尸线程,我不介意转储堆栈,我只是希望每个线程都停止(我将在这个线程中使用一些多处理,所以我想确保一切都停止一旦我按下 Ctrl+C 就死了) 【参考方案1】:

这是一个已知问题,在 Issue 35935 中进行了解释。

解决它的一种方法是使用signal.signal(signal.SIGINT, signal.SIG_DFL) 恢复到 SIGINT 的默认内核行为,(问题 OP 指出的解决方案)。至于为什么会这样,超出了我的知识范围。

这适用于使用 Python 3.8+ 的 Windows。

实施:

import time, threading
import signal


class MainClass(threading.Thread):

    def __init__(self):
        super().__init__()

    def run(self):
        while True:
            time.sleep(1)
            print("Looping")


# Script entry point
if __name__ == '__main__':
    a = MainClass()
    a.daemon=True
    signal.signal(signal.SIGINT, signal.SIG_DFL)
    a.start()
    a.join()

【讨论】:

以上是关于Ctrl+c 不停止 Windows + python3.7 中的线程的主要内容,如果未能解决你的问题,请参考以下文章

windows7总是出现windows资源管理器已停止服务是怎么回事

如何将VBS停止

tcpdump抓包按了Ctrl+C后依然没有停止抓包是为啥

为啥在“set /p”提示时使用 Ctrl+C 取消 Windows 批处理脚本会产生不一致的行为?

SBT 停止运行而不退出

redis