Python学习——执行python时,键盘按下ctrl+c,退出程序

在 Python 中,当用户按下 Ctrl+C 时,程序默认会触发 KeyboardInterrupt 异常并终止。


1. 捕获 KeyboardInterrupt 异常(推荐)

使用 try-except 块直接捕获 KeyboardInterrupt 异常,适用于简单场景。
示例代码

python 复制代码
try:
    while True:
        print("程序运行中,按 Ctrl+C 终止...")
except KeyboardInterrupt:
    print("\n检测到 Ctrl+C!执行清理操作后退出。")
  • 特点
    • 代码简洁,适合快速实现中断处理。
    • 可与其他异常(如 Exception)分开处理,避免混淆逻辑。
  • 适用场景:单线程脚本、需要即时响应中断的场景。

2. 使用 signal 模块处理信号

通过监听操作系统信号 SIGINT(对应 Ctrl+C)实现全局中断处理,适用于复杂场景(如资源清理或数据保存)。
示例代码

python 复制代码
import signal
import sys

def signal_handler(sig, frame):
    print("\n捕获到 Ctrl+C,正在保存数据...")
    sys.exit(0)

signal.signal(signal.SIGINT, signal_handler)  # 绑定信号处理器

while True:
    print("程序运行中,按 Ctrl+C 终止...")
  • 特点

    • 支持更灵活的信号处理(如同时处理 SIGTERM)。
    • 允许多线程环境中主线程统一管理中断。
  • 进阶用法 (封装为类):

    python 复制代码
    class DataProcessor:
        def __init__(self):
            self.data = []
            signal.signal(signal.SIGINT, self.handler)
    
        def handler(self, sig, frame):
            print(f"保存最后一条数据:{self.data[-1]}")
            sys.exit(0)
    
        def run(self):
            while True:
                self.data.append(len(self.data))

    通过类封装可保存中断时的状态(如最后处理的数据)。


3. 全局异常钩子(sys.excepthook

修改全局异常钩子,统一处理所有未捕获的异常(包括 KeyboardInterrupt)。
示例代码

python 复制代码
import sys
import time

def global_except_hook(exctype, value, traceback):
    if exctype == KeyboardInterrupt:
        print("\n全局捕获 Ctrl+C,正在终止...")
        sys.exit(0)
    sys.__excepthook__(exctype, value, traceback)  # 处理其他异常

sys.excepthook = global_except_hook

def main():
    while True:
        print("程序运行中...")
        time.sleep(1)

if __name__ == "__main__":
    main()
  • 特点 :适用于未显式使用 try-except 的场景,如第三方库代码引发的中断。

4. 多线程环境处理

在多线程中需注意信号处理的主线程绑定和线程间通信。
示例代码

python 复制代码
import signal
import threading

def worker():
    while True:
        print("工作线程运行中...")

def signal_handler(sig, frame):
    print("\n主线程收到 Ctrl+C,通知工作线程停止...")
    # 此处可设置事件标志通知线程退出
    exit(0)

signal.signal(signal.SIGINT, signal_handler)
thread = threading.Thread(target=worker)
thread.start()

while True:
    pass
  • 注意事项
    • 信号处理器需在主线程中注册。
    • 线程终止可通过事件标志(threading.Event)或队列(queue.Queue)实现协同。

5. 注意事项

  • 避免忽略异常 :直接 except: 会屏蔽所有异常,建议明确捕获 KeyboardInterrupt
  • 资源释放:在处理器中关闭文件、释放锁或回滚事务,防止数据损坏。
  • 信号处理限制 :部分信号(如 SIGKILL)无法被捕获。
  • 异步任务处理 :长时间运行的 C 扩展代码可能延迟信号响应,需结合 faulthandler 模块调试。

应用场景

场景 推荐方法 引用来源
简单脚本终止 try-except
复杂资源清理 signal 模块
全局未捕获异常处理 sys.excepthook
多线程/分布式程序 信号绑定 + 线程通信机制
相关推荐
这不小天嘛16 小时前
JAVA八股——J集合篇
java·开发语言
hboot17 小时前
AI工程师第五课 - 大语言模型基础
python·llm·fastapi
AOwhisky17 小时前
Python 学习笔记(第一期与第二期)——基础语法——核心知识点自测与详解
开发语言·笔记·python·学习·云原生·运维开发
天空'之城17 小时前
Linux 系统编程 22:五种 IO 模型全解
linux
STLearner18 小时前
ICML 2026 | LLM×Graph论文总结[1]【图基础模型,文本属性图,多模态属性图,图对齐,图提示学习,关系深度学习
论文阅读·人工智能·python·深度学习·学习·机器学习·数据挖掘
小张成长计划..19 小时前
【Linux】10:冯·诺依曼体系结构和操作系统
linux·运维·服务器
习明然19 小时前
我的本地化AI项目(三)
人工智能·python·electron·c#·avalonia
什巳19 小时前
JAVA练习278- 和为 K 的子数组
java·学习·算法·leetcode
喜欢的名字被抢了20 小时前
Python实战:SQLAlchemy ORM与FastAPI项目集成
开发语言·python·sql·教程·fastapi
碎光拾影20 小时前
CPU与MCU核心区别揭秘
单片机·学习·51单片机