当前位置: 首页 > news >正文

[Linux] Linux信号捕捉

在Linux中,信号捕捉是通过使用信号处理函数来实现的。信号是操作系统用于通知进程发生某些事件的机制,例如终止进程、外部中断、非法操作等。常用的信号捕捉机制是通过signal()函数或sigaction()函数来注册信号处理程序。

1. 使用signal()函数

signal()函数用于设置信号的处理函数,它的原型如下:

 
#include <signal.h>typedef void (*sighandler_t)(int);sighandler_t signal(int signum, sighandler_t handler);

  • signum:信号编号,表示要捕捉的信号。
  • handler:信号处理函数的指针,如果设置为SIG_IGN,表示忽略该信号;如果设置为SIG_DFL,表示使用默认的处理方法。
示例代码:捕捉SIGINT(Ctrl+C)
 
#include <stdio.h>
#include <signal.h>
#include <unistd.h>void sigint_handler(int sig) {printf("Caught signal %d (SIGINT)\n", sig);
}int main() {// 注册信号处理程序signal(SIGINT, sigint_handler);printf("Waiting for SIGINT signal...\n");// 进入一个无限循环,等待信号while (1) {sleep(1);}return 0;
}

当按下Ctrl+C时,程序会捕获到SIGINT信号并调用sigint_handler()函数。

2. 使用sigaction()函数

相比signal()函数,sigaction()提供了更多的控制选项,建议使用sigaction()进行信号捕捉。

sigaction()函数原型如下:

 
#include <signal.h>int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

  • signum:信号编号。
  • act:一个指向sigaction结构体的指针,指定信号的处理方式。
  • oldact:如果不为NULL,则该参数保存原来的信号处理方式。

sigaction结构体定义如下:

 
struct sigaction {void (*sa_handler)(int);   // 信号处理函数sigset_t sa_mask;          // 屏蔽信号集,在处理信号时阻塞的信号int sa_flags;              // 信号的处理标志void (*sa_sigaction)(int, siginfo_t *, void *); // 用于捕获更多信息的信号处理函数
};

示例代码:使用sigaction捕捉SIGTERM(终止信号)
 
#include <stdio.h>
#include <signal.h>
#include <unistd.h>void sigterm_handler(int sig) {printf("Caught signal %d (SIGTERM)\n", sig);
}int main() {struct sigaction sa;sa.sa_handler = sigterm_handler;  // 设置处理函数sigemptyset(&sa.sa_mask);         // 不阻塞其他信号sa.sa_flags = 0;// 注册信号处理程序sigaction(SIGTERM, &sa, NULL);printf("Waiting for SIGTERM signal...\n");// 进入一个无限循环,等待信号while (1) {sleep(1);}return 0;
}

在这个例子中,程序会捕获到SIGTERM信号并调用sigterm_handler()函数。

3. 信号常见的类型

一些常见的信号包括:

  • SIGINT:从键盘发送的中断信号(通常是Ctrl+C)。
  • SIGTERM:终止信号,用于优雅地终止进程。
  • SIGKILL:杀死进程信号,不能被捕捉或忽略。
  • SIGSEGV:段错误,表示非法访问内存。
  • SIGALRM:定时器到期信号。
  • SIGUSR1SIGUSR2:用户自定义信号。

你可以使用man 7 signal查看更多信号类型的详细信息。

总结

  • signal():简单的信号捕捉方法,但功能较少。
  • sigaction():更强大、灵活的信号捕捉方法,适合更复杂的应用场景。

对于生产环境中的信号捕捉,推荐使用sigaction()

http://www.lryc.cn/news/484192.html

相关文章:

  • Elasticsearch的查询语法——DSL 查询
  • 开发语言中,堆区和栈区的区别
  • 驾校增加无人机培训项目可行性技术分析
  • JavaWeb后端开发知识储备1
  • ISUP协议视频平台EasyCVR视频设备轨迹回放平台智慧农业视频远程监控管理方案
  • 大数据新视界 -- 大数据大厂之 Impala 存储格式转换:从原理到实践,开启大数据性能优化星际之旅(下)(20/30)
  • 百度搜索AI探索版多线程批量生成TXT原创文章软件-可生成3种类型文章
  • ubuntu20.04 解决Pytorch默认安装CPU版本的问题
  • 名词解释-2-形状算数实验、潜在空间、3D生成模型
  • Android 使用python统计getevent按键
  • NVIDIA jetson查看资源占用情况,打印/保存资源使用情况日志
  • ssm102“魅力”繁峙宣传网站的设计与实现+vue(论文+源码)_kaic
  • 逐行加载 HTML 内容并实时显示效果:使用 wxPython 的实现
  • UE4 Cook 从UAT传递参数给UE4Editor
  • 【学习日记】notebook添加JAVA支持
  • 以太坊系地址衍生算法分层确定性生成逻辑
  • 【Unity】ScriptableObject的应用:利用配方合成新物体
  • 31DNS设置
  • 使用Docker快速部署FastAPI Web应用
  • 全面掌握Spring Boot异常处理:策略与实践
  • 【LeetCode】【算法】11. 盛最多水的容器
  • ES6代理和反射新特性,详细讲解
  • vue计算属性 初步使用案例
  • 大模型时代,呼叫中心部门如何建设一套呼出机器人系统?
  • 使用Java绘制图片边框,解决微信小程序map组件中marker与label层级关系问题,label增加外边框后显示不能置与marker上面
  • 力扣 LeetCode 142. 环形链表II(Day2:链表)
  • 用MVVM设计模式提升WPF开发体验:分层架构与绑定实例解析
  • C++中的动态断言和静态断言
  • 运算放大器的学习(一)输入阻抗
  • Rust枚举之卧龙凤雏(Rust Option枚举、Rust Result枚举)(Rust Enum、Some(T)、Ok(T)、Err(E))链式操作