Linux进程信号——信号的捕捉、保存、处理

2024-08-27 13:36

本文主要是介绍Linux进程信号——信号的捕捉、保存、处理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

    • 信号的基本概念
    • 信号保存
      • block位图
      • pending位图
      • handler数组
    • 信号处理
      • sigset_t
      • sigemptyset
      • sigfillset
      • sigaddset sigdelset
      • sigismember
      • sigprocmask
    • 捕捉信号

信号的基本概念

  • 信号递达:实际处理信号的动作
  • 信号未决:信号从产生到递达之间的状态
  • 信号阻塞:不会被递达的信号
  • 信号忽略:递达的动作是忽略

阻塞和忽略的区别

阻塞指的是这个信号不会被递达,也就是不对其进行操作处理

忽略指的是这个信号可以递达,只是处理的动作是忽略

信号保存

在这里插入图片描述

在进程的PCB中有如下三个数据结构和信号相关

前两个是位图,后一个是数组

block位图

这个位图表示哪些信号被阻塞,0或1表示是否被阻塞,某一个位置表示对应的信号

pending位图

这个位图用来存储收到的信号,0或1表示是否收到,某一个位置表示对应的信号,这个位图也称之为信号集,也就是未决的情况

handler数组

这个数组是一个函数指针数组,里面的内容是函数指针,下标表示收到n号信号,调用的处理方法就是对应的函数指针

SIG_DFL宏代表这个函数是默认处理函数

SIG_IGN宏代表收到这个信号后,进行忽略这个信号

信号处理

在这里插入图片描述

这个函数可以手动更改handler数组,让进程在捕捉到对应信号的时候调用我们指定的函数处理

#include<iostream>
#include<signal.h>using namespace std;void func1(int signum)
{cout<<"进程捕捉到"<<signum<<"号信号,PID为:"<<getpid()<<endl;
}int main()
{signal(SIGINT, func1);while(1){cout<<"进程PID为:"<<getpid()<<endl;sleep(1);}return 0;
}

image.png

sigset_t

这个数据结构的本质是一个位图,其实就上面block位图和pending位图的数据结构

对于这个数据结构也有很多操作

sigemptyset

int sigemptyset(sigset_t *set)

这个函数是初始化set锁指向的信号集,对其置零,让其中不包含任何有效信号

sigfillset

int sigfillset(sigset_t *set)

这个函数是初始化全部置一,让其包含所有信号

sigaddset sigdelset

int sigaddset(sigset_t *set. int signo)

这两个是一对,分别对应添加和删除

需要注意的是,在使用sigset_t之前,一定要调用前面的任意一个初始化函数,让整个信号集处于确定的状态

sigismember

int sigismember(const sigset_t* set, int signo)

这个是用来判断是否有效,有效则返回1,无效返回0

sigprocmask

这个函数可以用于读取或更改阻塞信号集,也成为信号屏蔽字

int sigprocmask(int how, const sigset_t *set, sigset_t *oset)

成功返回0,出错返回-1

这里有几种情况

如果set和oset都不是空指针,这个函数就把原来的信号屏蔽字拷贝到oset中,然后按照how参数的规则进行修改

如果set非空而oset为空指针,这个函数就直接按照how进行修改而不拷贝

如果set为空指针而oset非空,则读取当前进程的信号屏蔽字

假设当前进程的信号屏蔽字是mask,我们期望更改的信号集是set

how的参数和功能如下

  • SIG_BLOCK:此时set信号集表示我们想要添加到信号屏蔽字中的信号,原理是使用位运算mask |= set;
  • SIG_UNBLOCK:此时set信号集表示我们希望从信号屏蔽字中接触阻塞的信号,使用位运算 mask = mask&~set;
  • SIG_SETMASK:此时set信号集表示我们想要变成的样子相当于直接赋值,mask = set;

捕捉信号

先说结论再说原理

当进程从内核态转换为用户态时,会自动进行信号的检测和捕捉处理

一般当代码进行执行的时候,操作系统是处于用户态的,但是执行到系统调用,或者出现异常中断时,操作系统会变成内核态

因为系统调用和异常处理的工作实际上是很底层的代码和函数,只有当操作系统处于内核态时才可以执行,此时这个进程的优先级非常高

最本质里面,其实就是在CPU中的CR3寄存器中,表示当前CPU处于什么状态,1表示内核态,3表示用户态,而这个寄存器对于用户也是不可见的,只由操作系统管理

也就是说当程序执行系统调用时会进入内核态

执行完系统调用时会回到用户态

在状态转换的时候,就进行信号的检测和处理

当这时有信号到来的时候,代码会跳转到信号处理的函数

当信号处理函数返回时还会执行特殊的系统调用,再回到内核态

大概流程如下图

在这里插入图片描述

这篇关于Linux进程信号——信号的捕捉、保存、处理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1111817

相关文章

Python使用vllm处理多模态数据的预处理技巧

《Python使用vllm处理多模态数据的预处理技巧》本文深入探讨了在Python环境下使用vLLM处理多模态数据的预处理技巧,我们将从基础概念出发,详细讲解文本、图像、音频等多模态数据的预处理方法,... 目录1. 背景介绍1.1 目的和范围1.2 预期读者1.3 文档结构概述1.4 术语表1.4.1 核

在Linux中改变echo输出颜色的实现方法

《在Linux中改变echo输出颜色的实现方法》在Linux系统的命令行环境下,为了使输出信息更加清晰、突出,便于用户快速识别和区分不同类型的信息,常常需要改变echo命令的输出颜色,所以本文给大家介... 目python录在linux中改变echo输出颜色的方法技术背景实现步骤使用ANSI转义码使用tpu

linux hostname设置全过程

《linuxhostname设置全过程》:本文主要介绍linuxhostname设置全过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录查询hostname设置步骤其它相关点hostid/etc/hostsEDChina编程A工具license破解注意事项总结以RHE

Spring Boot @RestControllerAdvice全局异常处理最佳实践

《SpringBoot@RestControllerAdvice全局异常处理最佳实践》本文详解SpringBoot中通过@RestControllerAdvice实现全局异常处理,强调代码复用、统... 目录前言一、为什么要使用全局异常处理?二、核心注解解析1. @RestControllerAdvice2

怎样通过分析GC日志来定位Java进程的内存问题

《怎样通过分析GC日志来定位Java进程的内存问题》:本文主要介绍怎样通过分析GC日志来定位Java进程的内存问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、GC 日志基础配置1. 启用详细 GC 日志2. 不同收集器的日志格式二、关键指标与分析维度1.

Java进程异常故障定位及排查过程

《Java进程异常故障定位及排查过程》:本文主要介绍Java进程异常故障定位及排查过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、故障发现与初步判断1. 监控系统告警2. 日志初步分析二、核心排查工具与步骤1. 进程状态检查2. CPU 飙升问题3. 内存

Linux中压缩、网络传输与系统监控工具的使用完整指南

《Linux中压缩、网络传输与系统监控工具的使用完整指南》在Linux系统管理中,压缩与传输工具是数据备份和远程协作的桥梁,而系统监控工具则是保障服务器稳定运行的眼睛,下面小编就来和大家详细介绍一下它... 目录引言一、压缩与解压:数据存储与传输的优化核心1. zip/unzip:通用压缩格式的便捷操作2.

Linux中SSH服务配置的全面指南

《Linux中SSH服务配置的全面指南》作为网络安全工程师,SSH(SecureShell)服务的安全配置是我们日常工作中不可忽视的重要环节,本文将从基础配置到高级安全加固,全面解析SSH服务的各项参... 目录概述基础配置详解端口与监听设置主机密钥配置认证机制强化禁用密码认证禁止root直接登录实现双因素

在Linux终端中统计非二进制文件行数的实现方法

《在Linux终端中统计非二进制文件行数的实现方法》在Linux系统中,有时需要统计非二进制文件(如CSV、TXT文件)的行数,而不希望手动打开文件进行查看,例如,在处理大型日志文件、数据文件时,了解... 目录在linux终端中统计非二进制文件的行数技术背景实现步骤1. 使用wc命令2. 使用grep命令

Linux如何快速检查服务器的硬件配置和性能指标

《Linux如何快速检查服务器的硬件配置和性能指标》在运维和开发工作中,我们经常需要快速检查Linux服务器的硬件配置和性能指标,本文将以CentOS为例,介绍如何通过命令行快速获取这些关键信息,... 目录引言一、查询CPU核心数编程(几C?)1. 使用 nproc(最简单)2. 使用 lscpu(详细信