You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows下Python多线程生产程序无法通过Ctrl+C中断的问题求助

解决Windows下Python多线程无法用Ctrl+C中断的问题

我之前也踩过完全一样的坑!Windows下Python的信号处理机制和Linux差异很大,这就是问题的核心——Ctrl+C触发的SIGINT信号只会被主线程接收,如果主线程被threading.Thread.join()这类操作死死阻塞,它根本没机会处理信号,子线程自然会一直跑下去。

先给你修正并完善代码,直接就能解决问题:

import threading
import time
import signal

class FooThread(threading.Thread):
    def __init__(self, stop_event):
        super().__init__()
        self.stop_event = stop_event

    def run(self):
        # 用线程安全的Event作为停止标志,替代原来的类变量
        while not self.stop_event.is_set():
            print("线程正在运行...")
            time.sleep(1)
        print("线程已终止")

def signal_handler(signum, frame):
    print("\n收到中断信号,准备终止程序...")
    stop_event.set()

if __name__ == "__main__":
    # 创建线程安全的停止事件
    stop_event = threading.Event()
    # 注册信号处理函数,让主线程能捕获Ctrl+C
    signal.signal(signal.SIGINT, signal_handler)

    thread = FooThread(stop_event)
    thread.start()

    # 主线程不要直接死等join,而是循环检查+超时等待,给信号处理留机会
    while thread.is_alive():
        thread.join(0.5)

关键要点解释:

  • 用threading.Event替代类变量:原来的stop_flag是类级别的共享变量,多线程场景下可能存在线程安全问题,Event是Python官方提供的线程安全标志位,可靠性更高。
  • 主线程不能阻塞在join():Windows下如果主线程一直卡在thread.join(),它完全无法响应SIGINT信号。改成带超时的循环等待,能让主线程定期“喘口气”处理信号。
  • 信号处理函数传递终止指令:捕获SIGINT后,通过Event通知子线程退出循环,实现优雅终止。

另外还有个简化方案:如果你的子线程不需要优雅释放资源,可以直接设置thread.daemon = True,这样主线程退出时会强制终止所有守护线程。但这种方式不够稳妥,可能导致资源泄漏,更推荐上面的优雅退出方案。

内容的提问来源于stack exchange,提问作者Dmitrii Vinokurov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:15:53