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

一篇文章带你快速了解linux中关于信号的核心内容

1. 信号概念

信号是操作系统用来通知进程某个特定事件已经发生的一种方式。它们是一种软件中断,可以被发送到进程以对其进行异步通知。

2. 信号处理的三种方式

  1. 执行默认动作
  2. 执行自定义动作
  3. 忽略

signal() 函数:将信号处理设置为 SIG_IGN,可以忽略信号

signal(sig, SIG_IGN);

sigaction() 函数:将 sa_handler 设置为 SIG_IGN

struct sigaction act;
act.sa_handler = SIG_IGN;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaction(sig, &act, NULL);

3. 系统定义的信号列表

131表示为常规信号,3264表示为实时信号

常规信号不需要排队,实时信号需要排队。

如果一个常规信号在短时间内多次产生,而进程正在处理前一个该信号,那么后续的相同信号通常会被丢弃,只保证至少有一个信号被传递给进程。

如果有多个相同的实时信号发送给一个进程,它们会被排队,直到进程有机会处理它们。这意味着进程可以按顺序处理所有接收到的实时信号,不会丢失任何信号。

信号编号信号名词信号用途
1SIGHUP通常在控制终端关闭时发送给前台进程组的所有进程,用于提示程序重新读取配置文件或优雅地重启
2SIGINT由用户发送,通常通过按下 Ctrl+C,请求程序中断当前操作
3SIGQUIT由用户发送,通常通过按下 Ctrl+\,请求程序停止并产生核心转储,用于调试
4SIGILL当程序尝试执行非法指令时发送,指示程序存在严重错误
5SIGTRAP由断点指令或trace调用触发,用于调试
6SIGABRTabort() 函数调用触发,请求程序异常终止并产生核心转储
7SIGBUS当程序试图访问一个无法访问的内存地址时发送,指示总线错误
8SIGFPE浮点异常信号,如算术溢出、除以零等
9SIGKILL用于立即终止进程,无法被捕获或忽略
10SIGUSR1用户自定义信号,可以用于进程间通信
11SIGSEGV段错误信号,当程序试图访问其内存空间中未分配或无法访问的内存时发送
12SIGUSR2用户自定义信号,可以用于进程间通信
13SIGPIPE当写入一个已被另一端关闭的管道时发送
14SIGALRM计时器信号,由 alarm() 函数设置的计时器超时触发
15SIGTERM终止信号,请求进程自行终止,是最常用的终止信号
16SIGSTKFLT协处理器栈故障,不常用
17SIGCHLD子进程结束或停止信号,用于通知父进程子进程的状态改变
18SIGCONT继续信号,用于将一个被停止的进程恢复执行
19SIGSTOP停止信号,用于暂停进程的执行,无法被捕获或忽略
20SIGTSTP用户停止信号,通常由用户通过 Ctrl+Z 触发
21SIGTTIN后台进程组试图从前台进程组控制的终端读取
22SIGTTOU后台进程组试图向前台进程组控制的终端写入
23SIGURG有紧急数据可读,通常用于网络编程
24SIGXCPUCPU时间限制超信号,当进程超过其CPU时间限制时发送
25SIGXFSZ文件大小限制超信号,当进程试图扩大超过其文件大小限制的文件时发送
26SIGVTALRM虚拟时钟超时信号,类似于 SIGALRM,但是计算的是进程占用 CPU 的时间
27SIGPROF性能分析信号,用于性能分析和监视
28SIGWINCH窗口变化信号,当终端的窗口大小发生变化时发送
29SIGIO输入/输出可用信号,用于异步I/O
30SIGPWR电源恢复信号,用于通知设备电源状态变化
31SIGSYS坏系统调用信号,当执行了无法识别的系统调用时发送

4. 信号的产生

4.1 通过终端按键产生信号

当用户在终端按键时(如 Ctrl+C 或 Ctrl+Z),终端驱动程序会捕捉到这个按键事件,并将其转换为相应的信号。

4.2 调用系统函向进程发信号

kill函数可以给一个指定的进程发送指定的信号

int kill(pid_t pid, int signo);//成功返回0,错误返回-1

raise函数可以给当前进程发送指定的信号(自己给自己发信号)

int raise(int signo);//成功返回0,错误返回-1

abort函数使当前进程接收到信号而异常终止

void abort(void);//abort函数总是会成功的,所以没有返回值

4.3 由软件条件产生信号

常见的软件条件:

  • 异常(SIGFPE、SIGSEGV)
  • 主动终止(SIGABRT)
  • 调试信息(SIGTRAP)
  • 自定义行为(SIGUSR1、SIGUSR2)

信号的生成和处理:

使用系统调用

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>int main() {// 主动触发 SIGABRT 信号abort();return 0;
}

捕捉和处理

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>void handle_sigint(int sig) {printf("Caught signal %d\n", sig);exit(0);
}int main() {signal(SIGINT, handle_sigint); // 捕获 Ctrl+Cwhile (1) {printf("Running...\n");sleep(1);}return 0;
}

4.4 硬件异常产生信号

在 Linux 中,硬件异常是指由计算机硬件引发的事件,这些事件通常会导致当前执行的程序无法继续正常运行。

硬件异常的常见问题:

非法指令:程序尝试执行未定义或不合法的指令

段错误:程序访问了未分配给它的内存区域

浮点异常:发生除以零、溢出等浮点运算错误

总线错误:由于对未对齐地址或无效地址进行访问而导致的错误

例如:

int main() {int *ptr = NULL;*ptr = 42; // 尝试写入 NULL 指针return 0;}

在这种情况下,CPU 检测到非法内存访问并生成 SIGSEGV 信号。操作系统捕获该信号并终止该进程,同时可能生成核心转储文件用于后续调试。

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

相关文章:

  • openEuler、Linux操作系统常见操作-(6)如何登录Linux
  • Python基础语法条件
  • 006-MAVEN 的使用
  • npm使用时报错:Could not retrieve https://npm.taobao.org/mirrors/node/index.json.
  • 软考中级网络工程师——高级配置
  • Leetcode 第 141 场双周赛题解
  • Linux性能调优,还可以从这些方面入手
  • STM32的独立看门狗定时器(IWDG)技术介绍
  • 自动化生成工作流?英伟达提出ComfyGen:通过LLM来匹配给定的文本提示与合适的工作流程
  • indicatorTree-v10练习(有问题)
  • python源码:指定麦克风/音响播放歌曲
  • 基于华为云智慧生活生态链设计的智能鱼缸
  • OJ-1015图像物体的边界
  • RAG 入门实践:从文档拆分到向量数据库与问答构建
  • 445: 选择问题
  • IP地址类型选择指南:动态IP、静态IP还是数据中心IP?
  • 基于Python flask的豆瓣电影可视化系统,豆瓣电影爬虫系统
  • 面试不是一场遭遇战
  • 【力扣 | SQL题 | 每日3题】力扣1795,1907,1398,602
  • centos7.9升级rockylinux8.8
  • C++初阶(三)---C++入门(下)
  • Linux--多路转接之epoll
  • 自动化工具Nico,从零开始干掉Appium,移动端自动化测试框架实现
  • Fast CRC32
  • 生成一个带有二维数据和对应标签的螺旋形数据集(非线性可分数据集)的代码解析
  • PHP unset() 函数的作用
  • 长篇故事可视化方法Story-Adapter:能够生成更高质量、更具细腻交互的故事图像,确保每一帧都能准确地传达故事情节。
  • C++基础面试题 | 什么是C++中的运算符重载?
  • 深入 IDEA 字节码世界:如何轻松查看 .class 文件?
  • NodeJS 利用代码生成工具编写GRPC