Python3实现捕获Ctrl+C终止信号

作者:DECHIN 时间:2021-10-17 14:03:55 

技术背景

对于一些连续运行或者长时间运行的Python程序而言,如服务器的后端,或者是长时间运行的科学计算程序。当我们涉及到一些中途退出的操作时,比如使用Ctrl+C来退出正在运行的程序。这种场景的出现一般有两个可能性:一是程序出现了问题,需要终止程序来对其进行调整。另一种是程序本身是正确的,但是程序运行的速度太慢了,也有可能是想提前结束,这种场景下很多时候我们是希望可以保留其相应的计算结果的。但是如果我们使用的是一些第三方的数据存储格式来存储数据,不一定可以支持连续的存储,非常常见的是在程序执行结束之后,再将结果进行保存。但是由于程序被提前终止了,此时就需要一些特殊的手段来对中途终止的程序的结果进行保存。

基础案例

我们先来看一个比较简单的案例:一个普通的打印数字的程序,每隔1s的时间就打印一个数字出来,我们可以使用python的signal.signal来捕获这个终止信号。

# signal_exit.py
import signal
import sys

def signal_handler(signal, frame):
   print ('\nSignal Catched! You have just type Ctrl+C!')
   sys.exit(0)

if __name__ == '__main__':
   import time

signal.signal(signal.SIGINT, signal_handler)
   for x in range(100):
       time.sleep(1)
       print (x)

当我们运行这个程序到一半时,同时按下Ctrl+C,我们会得到如下的结果:

$ python3 signal_exit.py
0
1
2
^C
Signal Catched! You have just type Ctrl+C!

这个结果表明,我们在程序运行的过程中捕获到了Ctrl+C的这个外部操作,并且对该操作进行了相应的处理之后,才终止了程序的运行。需要注意的是,如果此时不加上sys.exit(0)这个终止的操作,这个程序不会被停止,会继续运行下去,相当于只是捕获了异常终止信号但不做任何的处理。

给终止信号传入外部参数

在上面的一个案例中,仅仅只是捕获了“终止运行”的这个外部信号,但是如果更进一步的,我们想捕获到最后一个输出的数字是多少,这个时候要如何操作呢?signal.signal函数本身并不支持很多的参数传入,此时建议采取的是自行创建一个类,将signal_handler函数封装为类的成员函数,这样我们就可以获取到相应的内部参数,如下面这个案例所示:

# signal_exit.py
import signal
import sys
import time

class Printer:
   def __init__(self):
       self.x = 0
       signal.signal(signal.SIGINT, self.signal_handler)

def signal_handler(self, signal, frame):
       print ('\nSignal Catched! You have just type Ctrl+C! The last number is: {}'.format(self.x))
       sys.exit(0)

def run(self, counter=10):
       while self.x < counter:
           print (self.x)
           time.sleep(1)
           self.x += 1

if __name__ == '__main__':
   printer = Printer()
   printer.run(counter=100)

此时如果在程序正在运行的状态下同时按下Ctrl+C,得到的结果如下:

$ python3 signal_exit.py
0
1
2
3
^C
Signal Catched! You have just type Ctrl+C! The last number is: 3

可以看到,我们成功的捕获到了最后一个被输出出来的参数。

总结概要

当我们准备去杀死一个进程时,从程序设计的本身来考虑,我们应当要设计一定的保护方案来确保程序被非正常终止时,相应的计算结果也能够被很好的保存下来。在Python中可以使用signal.signal函数来实现这样的功能,但是如果要实现数据的保存功能,需要结合一个实际的类来实现。

来源:https://www.cnblogs.com/dechinphy/p/ctrlc.html

标签:Python,Ctrl+C
0
投稿

猜你喜欢

  • 在IE下获取object(ActiveX)的Param

    2009-05-15 13:07:00
  • 详解Python中Sync与Async执行速度快慢对比

    2023-02-06 13:26:45
  • linux下python中文乱码解决方案详解

    2023-09-01 03:53:04
  • Python的log日志功能及设置方法

    2022-03-28 22:13:32
  • Python实现的扫码工具居然这么好用!

    2022-12-13 19:54:03
  • Python cookbook(数据结构与算法)从序列中移除重复项且保持元素间顺序不变的方法

    2023-03-01 14:24:38
  • ASP.NET MVC中两个配置文件的作用详解

    2024-05-13 09:17:08
  • Django创建项目+连通mysql的操作方法

    2024-01-12 17:16:42
  • Python使用Nocalhost并开启debug调试的方法

    2023-05-04 11:22:46
  • pydev debugger: process 10341 is connecting无法debu的解决

    2022-11-02 12:04:00
  • Java字符串 正则表达式详解

    2023-07-16 12:30:35
  • Python 3.x基础实战检查磁盘可用空间

    2021-05-11 09:21:25
  • Windows下Anaconda的安装和简单使用方法

    2022-04-21 16:46:50
  • 使用Python实现给企业微信发送消息功能

    2021-06-10 15:30:07
  • 详解MySql基本查询、连接查询、子查询、正则表达查询

    2024-01-25 18:20:55
  • php教程之phpize使用方法

    2024-05-02 17:16:46
  • SQL Server中使用判断语句(IF ELSE/CASE WHEN )案例

    2024-01-18 22:04:53
  • 根据表名和索引获取需要的列名的存储过程

    2024-01-23 04:24:14
  • 简单了解为什么python函数后有多个括号

    2021-05-11 03:29:35
  • 如何使用Python多线程测试并发漏洞

    2021-11-18 08:25:52
  • asp之家 网络编程 m.aspxhome.com