Linux信号处理小知识:信号捕捉(SigCgt)

在Linux系统中,信号(Signal)是用来通知进程的一种机制。当进程接收到信号时,它可以选择执行默认行为、忽略该信号或者捕获该信号并进行处理。

我们可以通过执行kill -l命令来查看系统中可用的所有信号:

图 1: 列出所有信号

通常,我们使用的kill命令实际上是用来向进程发送信号的。默认情况下,它发送的是SIGTERM信号。而我们经常使用的kill -9 [PID]命令,其发送的信号是SIGKILL,这是一个强制终止进程的信号。

那么,我们如何知道进程注册了哪些信号的处理函数呢?可以通过查看SigCgt来了解。

实验 1:捕获SIGTERM信号

步骤 1:准备示例程序

首先,我们准备一个简单的shell脚本。这个脚本通过trap命令来捕获SIGTERM信号,并使用名为cleanup的函数来处理它。在没有接收到信号的时候,脚本会持续休眠。

bash 复制代码
#!/bin/bash

cleanup() {
  echo "Hello SIGTERM"
  echo "Do something for graceful stop..."
  exit
}

trap cleanup SIGTERM

while true;
  do
  echo "running for sleep"
  sleep 1
done

将上述代码保存为test.sh文件,并使用chmod +x test.sh命令使其可执行。运行后如下图:

图 2: test.sh 执行的结果

步骤 2:查看 SigCgt

首先使用ps aux命令找到该进程的PID,比如是9847,然后通过以下命令查看其SigCgt

shell 复制代码
# 找出 PID 为 9847 的进程的 SigCgt
# 记得要把 PID 换成你的 PID
$ cat /proc/9847/status | grep -i sigcgt
SigCgt: 0000000000014002

# 转成 2 进位:
$ echo "obase=2;ibase=16;0000000000014002" | bc
10100000000000010

由于SigCgt是以十六进制表示的,我们需要将其转换为二进制。转换后的结果是10100000000000010

步骤 3:查找对应的位置

图 3: SigCgt 对照

从二进制表示的SigCgt值中,我们可以看到第15位是1,这表明我们的程序捕获了SIGTERM信号。

实验 2:不捕捉 SIGTERM信号

步骤 1:准备示例程序

与实验1相同的示例程序,只需将trap命令注释掉,这样就不会捕获SIGTERM信号了。修改后,再次执行程序。

bash 复制代码
#!/bin/bash

cleanup() {
  echo "Hello SIGTERM"
  echo "Do something for graceful stop..."
  exit
}

# 把这行注解起来,也就是不再去捕捉 SIGTERM
#trap cleanup SIGTERM

while true;
  do
  echo "running for sleep"
  sleep 1
done

步骤 2:查看 SigCgt

同样地,使用ps aux找到进程的PID,然后查看其SigCgt

shell 复制代码
# 找出 PID 为 9847 的进程的 SigCgt
# 记得要把 PID 换成你的 PID
$ cat /proc/10644/status | grep -i sigcgt
SigCgt: 0000000000010002

# 转成 2 进位:
$ echo "obase=2;ibase=16;0000000000010002" | bc
10000000000000010

转换为二进制后,SigCgt的值变为10000000000000010

步骤 3:查找对应的位置

图 4: SigCgt 对照

通过修改示例程序中的trap信号处理,重复上述实验,可以看到SigCgt的值会相应地发生变化。

相关推荐
数研小生1 分钟前
淘宝宝贝详情数据爬虫:单线程采集突破方案(多线程 / 多进程实战)
linux·运维·爬虫
释怀不想释怀6 分钟前
Linux三剑客-sed
linux·运维·服务器
csdn_aspnet9 分钟前
如何在 ASP.NET Core Identity 中实现用户身份验证
后端·asp.net·.net core·identity
康小庄10 分钟前
SpringBoot 拦截器 (Interceptor) 与切面 (AOP):示例、作用、及适用场景
java·数据库·spring boot·后端·mysql·spring·spring cloud
中科院提名者26 分钟前
如何配置go环境并用vscode运行
开发语言·后端·golang
huahailing102434 分钟前
Spring Boot 3.x + JDK17 参数校验全场景实战(含List列表_嵌套_分组)
spring boot·后端
qq_1715203537 分钟前
linux服务器springboot(docker)项目word转pdf中文乱码
linux·spring boot·docker·pdf·word
老兵发新帖40 分钟前
Ubuntu安装fail2ban:防暴力破解
linux·运维·ubuntu
毕设源码-朱学姐1 小时前
【开题答辩全过程】以 基于spring boot的摩托车合格证管理系统为例,包含答辩的问题和答案
java·spring boot·后端
wdfk_prog1 小时前
[Linux]学习笔记系列 -- [drivers][clk]clk-bulk
linux·笔记·学习