Python signal 信号处理模块

2024-05-24 08:47:20 浏览数 (1)

在Python中,signal模块用于捕获和处理操作系统信号。信号是软件中断,通常由操作系统发送给进程,以通知进程发生了某个事件。例如,当用户按下Ctrl C时,操作系统会向进程发送SIGINT信号。在Linux中,kill命令用于向进程发送信号,默认情况下发送的是SIGTERM信号(15),这会导致进程终止。

signal模块允许你注册信号处理函数,这样当接收到特定信号时,可以执行自定义的代码。这对于在程序退出前执行清理操作非常有用,比如保存状态、关闭文件、释放资源等。

下面是一个简单的例子,展示了如何在Python程序中捕获SIGTERM信号(由kill命令默认发送),并执行一些清理操作:

代码语言:javascript复制
# _*_ coding: utf-8 _*_
# @Time : 2024/5/8 19:43
# @Author : Michael
# @File : signal_demo.py
# @desc

import signal
import time
import os

class FileSaver:
    def __init__(self):
        # 注册信号处理函数
        signal.signal(signal.SIGTERM, self.handle_signal)
        self.lines_written = 0

    def handle_signal(self, signum, frame):
        print(f"接收到信号 {signum},正在保存文件...")
        self.save()

    def save(self):
        # 模拟保存文件操作
        for _ in range(self.lines_written):
            print(f"保存行 {_   1}")
            time.sleep(0.05)  # 模拟保存
        print("文件保存完成。")
        # 退出程序
        os._exit(0)

    def write_line(self):
        # 模拟写入一行数据
        self.lines_written  = 1
        print(f"写入行 {self.lines_written}")

    def run(self):
        # 模拟程序运行,不断写入数据
        while True:
            self.write_line()
            time.sleep(1)  # 每秒写入一行

# 创建FileSaver实例并运行
saver = FileSaver()
saver.run()

在这个例子中,我们定义了一个handle_signal函数,它会在接收到SIGTERM信号时被调用。我们使用signal.signal(signal.SIGTERM, self.handle_signal)来注册这个处理函数。当程序运行时,如果接收到SIGTERM信号,比如通过在终端中执行kill <pid>(其中<pid>是程序的进程ID),程序会执行self.handle_signal函数中的代码,然后退出。

测试:

代码语言:javascript复制
(py38) $ nohup python -u signal_demo.py > nohup.out &
[1] 32635
(py38) $ nohup: ignoring input and redirecting stderr to stdout

(py38) $ tail -f nohup.out 
写入行 1
写入行 2
写入行 3
写入行 4
写入行 5
写入行 6
写入行 7
写入行 8
写入行 9
写入行 10
写入行 11
写入行 12
写入行 13
写入行 14
写入行 15
写入行 16

终端输入 kill 32635 ,默认是 15 信号

代码语言:javascript复制
接收到信号 15,正在保存文件...
保存行 1
保存行 2
保存行 3
保存行 4
保存行 5
保存行 6
保存行 7
保存行 8
保存行 9
保存行 10
保存行 11
保存行 12
保存行 13
保存行 14
保存行 15
保存行 16
文件保存完成。
^C
[1]   Done                    nohup python -u signal_demo.py > nohup.out

如果是 kill -9 则会强制立即关掉程序

0 人点赞