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

Linux学习笔记:信号

信号

  • 在Linux中什么是信号
  • 信号的产生方式
    • 硬件产生的信号
    • 软件产生的信号
    • 异常产生的信号
  • 进程对信号的处理
    • 信号的保存
    • 信号方法更改函数signal
      • 信号处理的更改
      • 恢复默认
      • 信号忽略
    • 信号的管理
      • 信号集 sigset_t
      • 对信号集的操作
    • 信号的捕捉过程

在Linux中什么是信号

在 Linux 系统中,信号是一种进程间通信的基本机制,用于通知进程发生了某种事件。
信号是一种软件中断,用于通知进程发生了某种事件。
这些事件可能包括硬件异常、用户输入、系统调用请求等。信号是异步发生的,即进程无法预测信号何时发生,但当信号发生时,系统会将信号发送给相应的进程。

在Linux中,信号一般被分为三大类:可以在bash使用kill -l 命令直接产看
在这里插入图片描述

  1. 标准信号(Standard Signals):由内核或进程向进程发送的信号,上图中的1-31号新号即为标准信号

  2. 实时信号(Real-time Signals):在标准信号的基础上引入了实时性概念,允许信号排队和按优先级传递,上图中的34-64即为实时信号

  3. 自定义信号(User-defined Signals):用户可以定义自己的信号类型,用于特定应用或通信需求。

信号的产生方式

无论信号有多少种产生方式,永远只能让OS向目标进程发送

硬件产生的信号

硬件产生的信号是由硬件设备或操作系统内核生成的,用于通知进程发生了某种事件。例如,当我们按下键盘上的^C键时,硬件会生成中断信号(SIGINT)来通知操作系统,然后操作系统将其传递给相应的进程

软件产生的信号

软件产生的信号是由进程自身或其他进程通过系统调用(如 kill )发送给目标进程的。这种方式允许进程之间进行通信和协作,例如向目标进程发送中断信号(SIGINT)以请求其终止执行:kill -9 pidnum

异常产生的信号

异常产生的信号是由硬件或操作系统检测到的异常事件引起的。例如,当进程执行非法指令、访问越界内存或发生浮点数异常时,硬件或操作系统会生成相应的信号(如 SIGILL、SIGSEGV、SIGFPE)来通知进程发生了异常情况。

进程对信号的处理

信号的保存

每个进程的PCB中都有一张自己的函数指针数组,一般被称为信号处理函数表,这个数组中的每个元素对应一个特定信号的处理函数。

当进程接收到信号时,操作系统会根据进程的PCB中的信号处理函数表找到对应的处理函数,并执行相应的逻辑。

以下是对信号处理的几个概念:

  1. 信号递达:实际信号的处理动作,一般有三种:默认,忽略,自定义
  2. 信号未决(pending):信号从产生到递达之间的状态,即在信号的位图中时,一斤产生但未被处理时的状态
  3. 信号阻塞(block):信号时允许被阻塞的,信号产生了,但暂时不进行递达的信号就是阻塞信号

因此操作系统会在进程PCB中创建三个表,用于对信号的状态进行记录,
其中,block表记录的是对应位置信号是否被屏蔽
pending表记录的是对应位置信号是否未决
handler表记录的事对应位置信号的执行方式
在这里插入图片描述

信号方法更改函数signal

信号处理的更改

在Linux中,信号处理函数 (signal) 是一种用来处理异步事件的方法。
信号是一个软件中断,通常由操作系统生成,用来通知程序某个事件已经发生,例如:非法操作、外部中断、定时器溢出等。

原型如下:

void (*signal(int signum, void (*handler)(int)))(int);

两个参数:

  1. signum:表示要设置的信号编号
  2. handler:表示要设置的信号处理函数,可以是一个函数指针,一般来说是我们自己写的一个函数,将signum所表示的信号重新实现

注意事项

  • 可重入性:信号处理函数应该是可重入的,即它们应该避免使用全局状态和执行非原子操作。
  • 限制:在信号处理函数中,只有少数几个函数是安全可调用的(通常称为异步信全函数)。例如,大多数系统调用和库函数都不应该在信号处理函数中调用。

举例:这是一个将2号信号进行更改,原本应该执行的功能被我修改成了handler函数内的内容

#include<iostream>
#include<signal.h>
#include<unistd.h>void handler(int signo)
{std::cout<< "获得一个" << signo << "号信号" << std::endl;exit(1);
}int main()
{signal(2,handler);return 0;
}

恢复默认

如果在开发过程中,忘记了自己之前对某个信号的执行更改,可以将signal函数的第二个参数传入宏:SIG_DFL来使得信号执行它默认的功能

signal(2,SIG_DFL);

信号忽略

在程序开发中,如果想要忽略某个信号,可以直接将signal函数的第二个参数传参宏:SIG_IGN

signal(2,SIG_IGN);

信号的管理

为了高效地处理多个信号,因此要先描述,再组织 , Linux提供了信号集的概念,使得可以将多个信号组合在一起进行处理。

信号集 sigset_t

sigset_t是一个用于表示信号集的数据类型,它通常定义在<signal.h>头文件中。
原型:

typedef struct sigset_t {unsigned long sig[_NSIG / sizeof(long)];
} sigset_t;

其中,_NSIG是一个宏,表示系统中定义的信号总数。sigset_t类型的信号集用于保存一个或多个信号的集合,可以通过位运算来操控信号集。

对信号集的操作

  1. 要创建一个空的信号集,可以使用以下代码:
sigset_t empty_set;
sigemptyset(&empty_set);

这样就有了一个新的信号集,这将清除empty_set中的所有信号位,使其成为一个空集。

  1. 创建一个全满的信号集:
sigset_t full_set;
sigfillset(&full_set);

这样就可以创建一个全满的信号集,并且将full_set中的所有信号位设置为1,表示设置了所有可能的信号。

  1. 设置或查询进程的信号前景,就好像设置权限掩码一样,对信号这些信号在进程处于等待状态(如在 select、poll、epoll_wait 等系统调用中)时会被优先处理:
void sigprocmask(int how, const sigset_t *set, sigset_t *oldset);

其中,how参数表示拷贝的方式,可以是SIG_BLOCK、SIG_UNBLOCK或SIG_SETMASK。set参数指向要拷贝的信号集,oldset参数用于接收旧的信号集。

  1. 添加信号集:
void sigaddset(sigset_t *set, int signum);

该函数将signum信号的位添加到set信号集中。

  1. 清除信号集:
void sigdelset(sigset_t *set, int signum);

该函数将signum信号的位从set信号集中删除。

  1. 检查信号是否存在于信号集中:
int sigismember(const sigset_t *set, int signum);

返回 1:如果指定的信号 signum 在信号集 set 中。
返回 0:如果指定的信号 signum 不在信号集 set 中。
返回 -1:如果发生错误(例如指定的信号编号无效),并且设置全局变量 errno

  1. 查询当前进程等待处理的信号集合,也就是查询处于pending状态的信号集合.这个函数可以帮助进程了解有哪些信号已经被生成但尚未被处理。
int sigpending(sigset_t *set);

当 sigpending 函数被调用时,它会将当前进程的信号等待集合(即那些已经被生成但尚未被处理或阻塞的信号)复制到 set 指向的 sigset_t 变量中。这样,进程就可以通过检查 set 中的信号位来确定有哪些信号需要处理。

下面是一个代码示例,我们首先使用 sigprocmask 函数屏蔽了 SIGINT 信号。然后,我们让进程睡眠5秒钟,以便有足够的时间让用户按下 Ctrl+C。在睡眠之后,我们调用 sigpending 函数来查询当前进程等待的信号。如果 SIGINT 信号在等待队列中,我们将打印出相应的信息。最后,我们使用 sigprocmask 函数恢复到旧的信号掩码,以便进程可以正常处理信号。

#include <signal.h>
#include <unistd.h>
#include <stdio.h>int main() {sigset_t pending_mask, empty_mask, old_mask;// 创建一个信号集合,用于存储 `SIGINT`sigemptyset(&empty_mask);sigaddset(&empty_mask, SIGINT); // 添加 SIGINT 到屏蔽集合// 阻止 SIGINT 信号if (sigprocmask(SIG_BLOCK, &empty_mask, &old_mask) == -1) {perror("sigprocmask");return 1;}printf("SIGINT 信号已被屏蔽,现在我将进入睡眠状态。\n");// 睡眠一段时间,以便有机会生成 SIGINT 信号sleep(5);// 查询当前进程等待的信号if (sigpending(&pending_mask) == -1) {perror("sigpending");return 1;}// 打印等待的信号if (sigismember(&pending_mask, SIGINT)) {printf("SIGINT 信号正在等待处理。\n");} else {printf("没有信号在等待处理。\n");}// 恢复旧的信号掩码if (sigprocmask(SIG_SETMASK, &old_mask, NULL) == -1) {perror("sigprocmask");return 1;}return 0;
}

信号的捕捉过程

如果信号的处理动作是用户自定义函数,在信号递达时就调用这个函数,这称为捕捉信号。
但是自定义信号处理函数是我们自己写的,是存在于用户空间的,因此这里涉及到一个用户到内核的转换问题,因为用户并不具有所有的操作权限,下面的图片可以很清楚的表达出信号捕捉过程中用户和内核态的转化过程
在这里插入图片描述
图片来自必应搜索

相关文章:

Linux学习笔记:信号

信号 在Linux中什么是信号信号的产生方式硬件产生的信号软件产生的信号异常产生的信号 进程对信号的处理信号的保存信号方法更改函数signal信号处理的更改恢复默认信号忽略 信号的管理信号集 sigset_t对信号集的操作 信号的捕捉过程 在Linux中什么是信号 在 Linux 系统中&…...

C#中的隐式类型转换和显式类型转换

在C#中&#xff0c;类型转换分为隐式类型转换&#xff08;Implicit Type Conversion&#xff09;和显式类型转换&#xff08;Explicit Type Conversion&#xff09;&#xff0c;也称为隐式转换和强制转换。 隐式类型转换&#xff08;Implicit Type Conversion&#xff09; 隐…...

linux上如何排查JVM内存过高?

在Linux上排查JVM内存过高的问题&#xff0c;可以采用以下几种方法&#xff1a; 1. **使用top命令查看进程**&#xff1a;通过top命令可以观察到系统中资源占用情况&#xff0c;包括CPU和内存。当收到内存过高的报警时&#xff0c;可以使用top命令来查看是哪个进程的内存使用率…...

第四届上海理工大学程序设计全国挑战赛 J.上学 题解 DFS 容斥

上学 题目描述 usst 小学里有 n 名学生&#xff0c;他们分别居住在 n 个地点&#xff0c;第 i 名学生居住在第 i 个地点&#xff0c;这些地点由 n−1 条双向道路连接&#xff0c;保证任意两个地点之间可以通过若干条双向道路抵达。学校则位于另外的第 0 个地点&#xff0c;第…...

word-排版文本基本格式

1、文本的基本格式&#xff1a;字体格式、段落格式 2、段落&#xff1a;word排版的基本控制单位 3、每敲一次回车&#xff0c;为一个段落标记&#xff0c;注意区分换行符和段落标记&#xff0c;换行符为指向下的箭头&#xff0c;段落标记为带拐弯的箭头&#xff0c;换行符&…...

目标检测YOLO实战应用案例100讲-无监督领域自适应目标检测方法研究与应用(五)

目录 多源无监督领域自适应目标检测方法 4.1研究现状及问题形成 4.2相关工作详述...

通过python实现Google的精准搜索

问题背景&#xff1a; 我想通过Google或者其他网站通过精准搜索确认该产品是否存在&#xff0c;但是即使该产品不存在Google也会返回一些相关的url链接&#xff0c;现在想通过python实现搜索结果的精准匹配以确认该产品是否为正确的名称【可以通过google搜索到&#xff0c;如果…...

Nios-II编程入门实验

文章目录 一 Verilog实现流水灯二 Nios实现流水灯2.1 创建项目2.2 SOPC添加模块2.3 SOPC输入输出连接2.4 Generate2.5 软件部分2.6 运行结果 三 Verilog实现串口3.1 代码3.2 引脚3.3 效果 四 Nios2实现串口4.1 sopc硬件设计4.2 top文件4.3 软件代码4.4 实现效果 五 参考资料六 …...

从0开始学python(七)

目录 前言 1 break、continue和pass函数 1.1 break 1.2 continue 1.3 pass 2、序列的索引及切片操作 2.1字符串的索引和切片 2.1.1 字符串索引 2.1.2 字符串切片 总结 前言 上一篇文章我们介绍了python中的循环结构&#xff0c;包括for和while的使用。本章接着往下讲。…...

【二叉树算法题记录】404. 左叶子之和

题目描述 给定二叉树的根节点 root &#xff0c;返回所有左叶子之和。 题目分析 其实这题无论是迭代法还是递归法&#xff0c;最重要的是要明确判断左叶子的条件&#xff1a;当前节点有左孩子&#xff0c;且这个左孩子没有它的左孩子和右孩子。 迭代法 感觉只要二叉树相关…...

面试集中营—Spring篇

Spring 框架的好处 1、轻量&#xff1a;spring是轻量的&#xff0c;基本的版本大约2MB&#xff1b; 2、IOC&#xff1a;控制反转&#xff0c;Spring的IOC机制使得对象之间的依赖不再需要我们自己来控制了&#xff0c;而是由容易来控制&#xff0c;一个字&#xff1a;爽&#xf…...

Lia 原理

训练阶段 论文流程&#xff1a; 具体实现&#xff1a; 通过latent space传递运动信息,实现分两部分。 1&#xff09;image space->latent space 将源图像映射到隐空间编码。X_s (source image )映射到编码Z_sr&#xff0c;通过W_rd方向上的变化&#xff0c;得到新的编码Z…...

文本批量操作技巧:内容查找不再繁琐,自动化批量移动至指定文件夹

在文本处理和信息管理的日常工作中&#xff0c;我们经常需要处理大量的文件和数据。面对这些海量的信息&#xff0c;如何快速而准确地查找特定的内容&#xff0c;并将它们批量移动至指定的文件夹&#xff0c;成为了一项关键的技能。本文将介绍办公提效工具一些实用的文本批量操…...

[数据结构]动画详解单链表

&#x1f496;&#x1f496;&#x1f496;欢迎来到我的博客&#xff0c;我是anmory&#x1f496;&#x1f496;&#x1f496; 又和大家见面了 欢迎来到动画详解数据结构系列 用通俗易懂的动画的动画使数据结构可视化 先来自我推荐一波 个人网站欢迎访问以及捐款 推荐阅读 如何低…...

图片批量管理迈入智能新时代:一键输入关键词,自动生成并保存惊艳图片,轻松开启创意之旅!

在数字化时代&#xff0c;图片已成为我们表达创意、记录生活、传递信息的重要工具。然而&#xff0c;随着图片数量的不断增加&#xff0c;如何高效、便捷地管理这些图片&#xff0c;却成为了一个令人头疼的问题。 第一步&#xff0c;进入首助编辑高手主页面&#xff0c;在上方…...

【硬件模块】ESP-01SWiFi模块基于AT指令详解(WiFi,TCP/IP,MQTT)

ESP-01S ESP-01S是由安信可科技开发的一款Wi-Fi模块。其核心处理器是ESP8266&#xff0c;该处理器在较小尺寸的封装中集成了业界领先的Tensilica L106超低功耗32位微型MCU&#xff0c;带有16位精简模式&#xff0c;主频支持80MHz和160MHz&#xff0c;并集成了Wi-Fi MAC/BB/RF/P…...

数据结构之单单单——链表

目录 一.链表 1&#xff09;链表的概念 2&#xff09;链表的结构 二.单链表的实现 三.链表的分类 1&#xff09;单向或者双向 2&#xff09;带头或不带头 3&#xff09;循环或非循环 一.链表 1&#xff09;链表的概念 链表&#xff08;Linked List&#xff09;是一种…...

【Linux笔记】 基础指令(二)

风住尘香花已尽 日晚倦梳头 重命名、剪切指令 -- mv 简介&#xff1a; mv 命令是 move 的缩写&#xff0c;可以用来移动文件或者将文件改名&#xff0c;是 Linux 系统下常用的命令&#xff0c;经常用来备份文件或者目录 语法&#xff1a; mv [选项] 源文件或目录 目标文件或目录…...

软件全套资料梳理(需求、开发、实施、运维、安全、测试、交付、认证、评审、投标等)

软件全套精华资料包清单部分文件列表&#xff1a; 工作安排任务书&#xff0c;可行性分析报告&#xff0c;立项申请审批表&#xff0c;产品需求规格说明书&#xff0c;需求调研计划&#xff0c;用户需求调查单&#xff0c;用户需求说明书&#xff0c;概要设计说明书&#xff0c…...

javacv实时解析pcm音频流

javacv实时解析pcm音频流 解析代码 try (ByteArrayInputStream inputStream new ByteArrayInputStream(bytes);){FFmpegFrameGrabber grabber new FFmpegFrameGrabber(inputStream);// PCM S16LE 格式grabber.setFormat("s16le");// 采样率grabber.setSampleRate(1…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略&#xff0c;并且实现了基本的选区操作&#xff0c;还调研了自绘选区的实现。那么相对的&#xff0c;我们还需要设计编辑器的选区表达&#xff0c;也可以称为模型选区。编辑器中应用变更时的操作范围&#xff0c;就是以模型选区为基准来…...

基于服务器使用 apt 安装、配置 Nginx

&#x1f9fe; 一、查看可安装的 Nginx 版本 首先&#xff0c;你可以运行以下命令查看可用版本&#xff1a; apt-cache madison nginx-core输出示例&#xff1a; nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

2021-03-15 iview一些问题

1.iview 在使用tree组件时&#xff0c;发现没有set类的方法&#xff0c;只有get&#xff0c;那么要改变tree值&#xff0c;只能遍历treeData&#xff0c;递归修改treeData的checked&#xff0c;发现无法更改&#xff0c;原因在于check模式下&#xff0c;子元素的勾选状态跟父节…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析&#xff08;97/126&#xff09;&#xff1a;邮件营销与用户参与度的关键指标优化指南 在数字化营销时代&#xff0c;邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天&#xff0c;我们将深入解析邮件打开率、网站可用性、页面参与时…...

Selenium常用函数介绍

目录 一&#xff0c;元素定位 1.1 cssSeector 1.2 xpath 二&#xff0c;操作测试对象 三&#xff0c;窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四&#xff0c;弹窗 五&#xff0c;等待 六&#xff0c;导航 七&#xff0c;文件上传 …...