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

相关文章

Linux搭建单机MySQL8.0.26版本的操作方法

《Linux搭建单机MySQL8.0.26版本的操作方法》:本文主要介绍Linux搭建单机MySQL8.0.26版本的操作方法,本文通过图文并茂的形式给大家讲解的非常详细,感兴趣的朋友一起看看吧... 目录概述环境信息数据库服务安装步骤下载前置依赖服务下载方式一:进入官网下载,并上传到宿主机中,适合离线环境

一文带你搞懂Redis Stream的6种消息处理模式

《一文带你搞懂RedisStream的6种消息处理模式》Redis5.0版本引入的Stream数据类型,为Redis生态带来了强大而灵活的消息队列功能,本文将为大家详细介绍RedisStream的6... 目录1. 简单消费模式(Simple Consumption)基本概念核心命令实现示例使用场景优缺点2

windows和Linux使用命令行计算文件的MD5值

《windows和Linux使用命令行计算文件的MD5值》在Windows和Linux系统中,您可以使用命令行(终端或命令提示符)来计算文件的MD5值,文章介绍了在Windows和Linux/macO... 目录在Windows上:在linux或MACOS上:总结在Windows上:可以使用certuti

Linux之systemV共享内存方式

《Linux之systemV共享内存方式》:本文主要介绍Linux之systemV共享内存方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、工作原理二、系统调用接口1、申请共享内存(一)key的获取(二)共享内存的申请2、将共享内存段连接到进程地址空间3、将

Java 中的 @SneakyThrows 注解使用方法(简化异常处理的利与弊)

《Java中的@SneakyThrows注解使用方法(简化异常处理的利与弊)》为了简化异常处理,Lombok提供了一个强大的注解@SneakyThrows,本文将详细介绍@SneakyThro... 目录1. @SneakyThrows 简介 1.1 什么是 Lombok?2. @SneakyThrows

在 Spring Boot 中实现异常处理最佳实践

《在SpringBoot中实现异常处理最佳实践》本文介绍如何在SpringBoot中实现异常处理,涵盖核心概念、实现方法、与先前查询的集成、性能分析、常见问题和最佳实践,感兴趣的朋友一起看看吧... 目录一、Spring Boot 异常处理的背景与核心概念1.1 为什么需要异常处理?1.2 Spring B

python处理带有时区的日期和时间数据

《python处理带有时区的日期和时间数据》这篇文章主要为大家详细介绍了如何在Python中使用pytz库处理时区信息,包括获取当前UTC时间,转换为特定时区等,有需要的小伙伴可以参考一下... 目录时区基本信息python datetime使用timezonepandas处理时区数据知识延展时区基本信息

快速修复一个Panic的Linux内核的技巧

《快速修复一个Panic的Linux内核的技巧》Linux系统中运行了不当的mkinitcpio操作导致内核文件不能正常工作,重启的时候,内核启动中止于Panic状态,该怎么解决这个问题呢?下面我们就... 感谢China编程(www.chinasem.cn)网友 鸢一雨音 的投稿写这篇文章是有原因的。为了配置完

Python Transformers库(NLP处理库)案例代码讲解

《PythonTransformers库(NLP处理库)案例代码讲解》本文介绍transformers库的全面讲解,包含基础知识、高级用法、案例代码及学习路径,内容经过组织,适合不同阶段的学习者,对... 目录一、基础知识1. Transformers 库简介2. 安装与环境配置3. 快速上手示例二、核心模

一文详解Java异常处理你都了解哪些知识

《一文详解Java异常处理你都了解哪些知识》:本文主要介绍Java异常处理的相关资料,包括异常的分类、捕获和处理异常的语法、常见的异常类型以及自定义异常的实现,文中通过代码介绍的非常详细,需要的朋... 目录前言一、什么是异常二、异常的分类2.1 受检异常2.2 非受检异常三、异常处理的语法3.1 try-