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
多线程/分布式程序 信号绑定 + 线程通信机制
相关推荐
好大哥呀11 分钟前
Java Web的学习路径
java·前端·学习
odoo中国38 分钟前
Odoo 19 模块结构概述
开发语言·python·module·odoo·核心组件·py文件按
Jelena1577958579241 分钟前
Java爬虫api接口测试
python
Uncertainty!!1 小时前
Linux多用户情况下个别用户输入密码后黑屏
linux·远程连接
necessary6531 小时前
使用Clion查看linux环境中的PG源码
linux·运维·服务器
代码N年归来仍是新手村成员1 小时前
【Java转Go】即时通信系统代码分析(一)基础Server 构建
java·开发语言·golang
踩坑记录2 小时前
leetcode hot100 3.无重复字符的最长子串 medium 滑动窗口(双指针)
python·leetcode
Z1Jxxx2 小时前
01序列01序列
开发语言·c++·算法
沐知全栈开发2 小时前
C语言中的强制类型转换
开发语言
梦雨羊2 小时前
Base-NLP学习
人工智能·学习·自然语言处理