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使用fdisk进行磁盘的相关操作

《Linux使用fdisk进行磁盘的相关操作》fdisk命令是Linux中用于管理磁盘分区的强大文本实用程序,这篇文章主要为大家详细介绍了如何使用fdisk进行磁盘的相关操作,需要的可以了解下... 目录简介基本语法示例用法列出所有分区查看指定磁盘的区分管理指定的磁盘进入交互式模式创建一个新的分区删除一个存

Linux使用dd命令来复制和转换数据的操作方法

《Linux使用dd命令来复制和转换数据的操作方法》Linux中的dd命令是一个功能强大的数据复制和转换实用程序,它以较低级别运行,通常用于创建可启动的USB驱动器、克隆磁盘和生成随机数据等任务,本文... 目录简介功能和能力语法常用选项示例用法基础用法创建可启动www.chinasem.cn的 USB 驱动

高效管理你的Linux系统: Debian操作系统常用命令指南

《高效管理你的Linux系统:Debian操作系统常用命令指南》在Debian操作系统中,了解和掌握常用命令对于提高工作效率和系统管理至关重要,本文将详细介绍Debian的常用命令,帮助读者更好地使... Debian是一个流行的linux发行版,它以其稳定性、强大的软件包管理和丰富的社区资源而闻名。在使用

Go语言使用Buffer实现高性能处理字节和字符

《Go语言使用Buffer实现高性能处理字节和字符》在Go中,bytes.Buffer是一个非常高效的类型,用于处理字节数据的读写操作,本文将详细介绍一下如何使用Buffer实现高性能处理字节和... 目录1. bytes.Buffer 的基本用法1.1. 创建和初始化 Buffer1.2. 使用 Writ

Python视频处理库VidGear使用小结

《Python视频处理库VidGear使用小结》VidGear是一个高性能的Python视频处理库,本文主要介绍了Python视频处理库VidGear使用小结,文中通过示例代码介绍的非常详细,对大家的... 目录一、VidGear的安装二、VidGear的主要功能三、VidGear的使用示例四、VidGea

Python结合requests和Cheerio处理网页内容的操作步骤

《Python结合requests和Cheerio处理网页内容的操作步骤》Python因其简洁明了的语法和强大的库支持,成为了编写爬虫程序的首选语言之一,requests库是Python中用于发送HT... 目录一、前言二、环境搭建三、requests库的基本使用四、Cheerio库的基本使用五、结合req

使用Python处理CSV和Excel文件的操作方法

《使用Python处理CSV和Excel文件的操作方法》在数据分析、自动化和日常开发中,CSV和Excel文件是非常常见的数据存储格式,ython提供了强大的工具来读取、编辑和保存这两种文件,满足从基... 目录1. CSV 文件概述和处理方法1.1 CSV 文件格式的基本介绍1.2 使用 python 内

Linux Mint Xia 22.1重磅发布: 重要更新一览

《LinuxMintXia22.1重磅发布:重要更新一览》Beta版LinuxMint“Xia”22.1发布,新版本基于Ubuntu24.04,内核版本为Linux6.8,这... linux Mint 22.1「Xia」正式发布啦!这次更新带来了诸多优化和改进,进一步巩固了 Mint 在 Linux 桌面

LinuxMint怎么安装? Linux Mint22下载安装图文教程

《LinuxMint怎么安装?LinuxMint22下载安装图文教程》LinuxMint22发布以后,有很多新功能,很多朋友想要下载并安装,该怎么操作呢?下面我们就来看看详细安装指南... linux Mint 是一款基于 Ubuntu 的流行发行版,凭借其现代、精致、易于使用的特性,深受小伙伴们所喜爱。对

什么是 Linux Mint? 适合初学者体验的桌面操作系统

《什么是LinuxMint?适合初学者体验的桌面操作系统》今天带你全面了解LinuxMint,包括它的历史、功能、版本以及独特亮点,话不多说,马上开始吧... linux Mint 是一款基于 Ubuntu 和 Debian 的知名发行版,它的用户体验非常友好,深受广大 Linux 爱好者和日常用户的青睐,