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

Linux:信号保存与处理

使用kill -l命令查看信号:

信号量和信号确实一点关系没有

信号是操作系统发出的进程与进程之间的通知于中断,是进程之间时间异步通知的一种方式

先了解同步通信:同步通信是一种比特同步通信技术,要求发收双方具有同频同相的同步时钟信号,只需在传送报文的最前面附加特定的同步字符,使发收双方建立同步,此后便在同步时钟的控制下逐位发送/接收。

优点是效率高,缺点是硬件要求高

什么叫异步通信:异步通信是指发送方在向接收方发送数据的时候可以有任意的时间间隔,没有严格的时序要求,而接收方需要一直存在,来接收数据

优点是便宜,缺点是效率低

信号量是一个计时器,表示可用资源的数量

进程产生信号的方式有四种

通过终端按键发出信号

例如你输入ctrl c的时候可以中断进程,ctrl \是离开信号,ctrl z是暂停信号

这些信号分别对应了上图的2信号,3信号,20信号

通过系统调用函数产生信号

kill命令在实现的时候也是调用kill函数实现的,kill函数可以给指定进程发送指定的信号

#include<signal.h>

int kill(pid_t pid,int signo);

来写一个kill函数的调用:

mykill:

#include<stdio.h>
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>
#include<stdlib.h>
int main(int argc,char *argv[]){if(argc!=3){perror("kill false");return 1;}pid_t pid=atoi(argv[2]);int sig=atoi(argv[1]);kill(pid,sig);//啊啊啊啊,一开始写反参数的顺序了,气死了return 0;
}

myprocess.c:

#include<stdio.h>
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>
void handler(int sig){printf("get a sig form myskill,sig==%d",sig);
}int main(){signal(2,handler);//signal是个系统调用函数,第一个参数是输入的信号是几,第二个参数有三种类型//此处的类型为一个函数指针,在执行该语句的时候执行一个handler函数,这个函数是要自己声明的//格式为int handler(int sig)while(1){printf("a process,pid==%d\n",getpid());fflush(stdout);sleep(1);}return 0;
}

除了kill函数还有abort函数,使当前进程接收到信号而异常终止

#include<stdlib.h>

void abort(void)

用go也写一个:

package mainimport ("fmt""os""os/signal""syscall"
)func main() {sigs := make(chan os.Signal, 1)done := make(chan bool, 1)signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) //将sigint和sigterm的信号传给sig//process start//get a sig interrupt,这个interrupt就是syscall.SIGINT返回的信号go func() {sig := <-sigs//将信号发送给sigfmt.Println("get a sig", sig)done <- true//标为结束}()fmt.Println("process start")<-done
}

myabort.c:

#include<signal.h>
#include<sys/types.h>
#include<unistd.h>
#include<stdlib.h>
void handler(int sig){printf("get a sig");
}
int main(){signal(3,handler);//捕获信号while(1){sleep(1);abort();//捕获之后就终止进程,因为abort就是终止}return 0;
}

那abort()函数收到信号会终止,那么是不是我让他捕捉所有的信号,就不能终止我的进程了?

void catchSig(int signum)
{printf("get a signal:%d",signum);
}
int main()
{for(int sig = 1; sig <= 31; sig++) {signal(sig, catchSig);}while(true){sleep(1);}return 0;
}

信号9不能被自动捕捉哦

但是我们还是可以用kill -9 pid来终止该进程:

还有raise,是给自己当前的进程发送信号:

#include<stdio.h>
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>
#include<stdlib.h>
void handler(int sig){printf("get a sig,sig==%d\n",sig);fflush(stdout);
}
int main(){signal(3,handler);while(1){sleep(1);raise(3);//给当前进程发送信号3}return 0;
}

由软件条件产生的信号

上图的信号13是一个管道中由软件产生的信号,读端关闭,写端一直写入的时候,os会直接啥的写端进程,怎么杀掉呢?通过向目标文件发送SIGPIPE(13)信号,终止目标进程,这就叫软件条件

由硬件异常生成的信号

硬件发生异常后以某种方式被检测到并且通知到内核,内核再向进程发送适当的信号(也是设计到软件条件产生的信号)

软件条件和硬件异常的产生的信号的区别:软件条件就是操作系统和应用程序内部生成的,硬件信号是物理设备(外设)通过中断机制发送

进程递达,阻塞和捕捉

一个信号在发送给一个进程的时候需要三个阶段:这个信号我收不收?这个信号我要不要写入?我写入/或者不写入用不用?

表现出来就是一个task_struct下的三个标志位:block(要不要阻塞,对应前面的这个信号我收不收),pending(bit位的位置表示编号,不同位置代表不同的信号,对应位置的信号写入,则置为1,否则置为0),例如,block 位图的最低一个比特位就表示是否对 1 号信号进行阻塞,pending 位图的最低一个比特位就表示是否收到 1 号信号。

bandler(这个信号我要不要忽视=这个信号我用不用)

阻塞和忽略是不同的,阻塞是不接收这个信号,忽略是接收这个信号,写入该信号,但是不执行这个信号;也就是说信号被阻塞就不能递达,递达之后才能选择你能不能忽略

信号递达:执行信号的处理动作称为信号递达(Delivery)

信号从产生到递达(从有信号到执行信号的状态)称为信号未决(Pending)

信号集

能表示多个信号的一种数据类型,叫信号集(signal set,信号集其实就是 sigset_t 类型数据结构)

在阻塞信号集下的每个信号的“有效”和“无效”指的是这个信号有没有被阻塞,在未决信号集下的有无效是指是否处于未决状态

阻塞信号集也叫信号屏蔽字(Signal Mask),这里的屏蔽的意思==阻塞

sigset_t下的每个信号都用每个bit来判定信号是有效还是无效

设置信号集

通过函数设置信号集

#include <signal.h>
int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigaddset (sigset_t *set, int signo);
int sigdelset(sigset_t *set, int signo);
int sigismember(const sigset_t *set, int signo);

我们来解释一下这些函数

sigemptyset(),用于清空(初始化)信号集,使其中所有的信号对应的bit清零,表示该信号集不包含有效信号

sigfillset(),也是初始化信号集内的信号,但是与sigemptyset()的区别是sigfillset()是置位,全部置为有效信号

每次使用sigset_t类型的变量之前,一定要调用sigemptyset或sigfillset做初始化,初始化后就可以调用其他的如sigaddset或sigdelset做添加或删除某种有效信号

这四个函数的返回值都是成功返回0,失败返回-1

而sigismember是个bool类型的函数,用于判断该信号集是否包含某种信号,包含返回1,不包含返回0,出错返回-1

维护信号集

调用函数sigprocmask()可以读取或更改进程的信号屏蔽字,也就是阻塞信号集

#include <signal.h>
int sigprocmask(int how, const sigset_t *set, sigset_t *oset);
// 返回值:若成功则为0,若出错则为-1

若oset是非空指针,则读取进程的当前信号屏蔽字通过oset参数传出(输出型参数)

如果set是非空指针,则更改进程的信号屏蔽字,参数how指示如何更改

如果oset和set都是非空指针,则将原来的信号屏蔽字备份到oset里,然后根据how和set来修改信号屏蔽字

若mask是我们当前的信号屏蔽字,这是how的可选选项

如果调用 sigprocmask 解除了对当前若干个未决信号的阻塞,则在sigprocmask返回前,至少将其中一个信号递达。

原理:一个信号被阻塞,也就是在信号屏蔽字内的时候,就处于未决状态;当调用过sigprocmask就意味着至少有一个信号得进入递达状态(内核至少递送一个信号)

读取当前进程的信号集

#include <signal.h>
sigpending(&s);

sigpending 函数可以读取当前进程的未决信号集,通过 s 参数传出。调用成功则返回0,出错则返回-1。

信号捕捉的过程

信号在内核态返回到用户态进行信号的检测和处理

如果处理信号的函数是用户自定义的函数,那么在信号递达的时候调用这个函数,称为捕捉信号。

在信号捕捉中,一共会涉及到四次状态转换

可重入函数

可重入函数(reentrant function)是指在多个执行流下,能够被同时调用而不会产生冲突或错误的函数。

这种函数能够保证在任意时刻,无论被同一个还是不同执行流调用,都能正确地完成预期的功能。

如果一个函数符合以下条件之一则是不可重入的:

调用了malloc或free,因为malloc也是用全局链表来管理堆的。
调用了标准I/O库函数,标准I/O库的很多实现都以不可重入的方式使用全局数据结构。

相关文章:

Linux:信号保存与处理

使用kill -l命令查看信号&#xff1a; 信号量和信号确实一点关系没有 信号是操作系统发出的进程与进程之间的通知于中断&#xff0c;是进程之间时间异步通知的一种方式 先了解同步通信&#xff1a;同步通信是一种比特同步通信技术&#xff0c;要求发收双方具有同频同相的同步…...

工具方法 - 可选的一些AI聊天机器人

1, ChatGPT OpenAI https://chatgpt.com/ 2, Microsoft Copilot Microsoft Copilot: 你的 AI 助手 Microsoft Copilot: 你的 AI 助手 3, HuggingChat Hugging Face – The AI community building the future. https://huggingface.co/ https://huggingface.co/chat/ 4,…...

YOLOv11改进策略【卷积层】| CVPR-2023 ScConv:即插即用,减少冗余计算并提升特征学习

一、本文介绍 本文记录的是利用ScConv优化YOLOv11的目标检测网络模型。深度神经网络中存在大量冗余,不仅在密集模型参数中,而且在特征图的空间和通道维度中。ScConv模块通过联合减少卷积层中空间和通道的冗余,有效地限制了特征冗余,本文利用ScConv模块改进YOLOv11,提高了…...

总结拓展十四:批次管理(2)

1、批次管理后台配置 1.1 批次管理级别配置(T-code:OMTC) ——路径&#xff1a;IMG->后勤-常规->批次管理->指定级别并激活状态管理 1.2 批次状态管理配置(T-code:OMTC) ——路径&#xff1a;IMG->后勤-常规->批次管理->指定级别并激活状态管理 批状态管…...

架构设计笔记-18-安全架构设计理论与实践

知识要点 常见的安全威胁&#xff1a; 信息泄露&#xff1a;信息被泄露或透露给某个非授权的实体。破坏信息的完整性&#xff1a;数据被非授权地进行增删、修改或破坏而受到损失。拒绝服务&#xff1a;对信息或其他资源的合法访问被无条件地阻止。攻击者向服务器发送大量垃圾…...

Python网络爬虫

随着互联网的迅猛发展&#xff0c;数据成为了新的“石油”。人们对于信息的需求日益增涨&#xff0c;尤其是在市场分析、学术研究和数据挖掘等领域。网络爬虫作为一种自动提取网络数据的技术&#xff0c;因其强大的能力而备受关注。而Python&#xff0c;凭借其简洁的语法和丰富…...

38. 外观数列

目录 一、问题描述 二、解题思路 三、代码 四、复杂度分析 一、问题描述 「外观数列」是一个数位字符串序列&#xff0c;由递归公式定义&#xff1a; countAndSay(1) "1"countAndSay(n) 是 countAndSay(n-1) 的行程长度编码。 行程长度编码&#xff08;RLE&am…...

Android中的三种数据存储方式

目录 1.文件存储 1&#xff09;内部存储 1--MODE_PRIVATE: 2--MODE_APPEND: 3--MODE_WORLD_READABLE: 4--MODE_WORLD_WRITEABLE: 5--简单使用 3&#xff09;外部存储 4&#xff09;内部读取 4&#xff09;外部读取 2.SharePreferences存储 1&#xff09;基本概念 2&#xff09…...

VS2022中Qt环境配置步骤

VS2022中Qt环境配置步骤 一、安装QT 下载QT&#xff1a;从QT官网上下载QT&#xff0c;在安装过程中&#xff0c;可以根据自己的需求选择适合的QT版本。若不确定&#xff0c;建议选择最新版本&#xff0c;这有助于提高开发效率。 二、安装Visual Studio 2022 选择组件&#…...

【前端】 常用的版本控制符号汇总

前端的版本控制符主要用于管理前端项目中依赖包的版本。它们通常在package.json文件中定义&#xff0c;帮助开发者指定所需的库和框架的版本范围。以下是一些关键概念&#xff1a; 版本控制符号详解&#xff1a; 1. 依赖管理 在前端开发中&#xff0c;依赖管理工具&#xff…...

OWASP Top 10 漏洞详解:基础知识、面试常问问题与实际应用

OWASP&#xff08;开放式Web应用程序安全项目&#xff09;是一个全球性非营利组织&#xff0c;致力于提高软件安全性。OWASP Top 10 是其发布的十大Web应用程序安全风险列表&#xff0c;广泛应用于安全领域的学习和实践。本文将详细介绍OWASP Top 10 漏洞的基础知识、面试常见问…...

实景三维赋能自然资源精细化管理创新

在自然资源管理领域&#xff0c;如何实现精细化、高效化管理一直是我们面临的挑战。随着实景三维技术的兴起&#xff0c;这一挑战迎来了新的解决方案。今天&#xff0c;我们将探讨实景三维技术如何赋能自然资源的精细化管理。 1. 实景三维技术概述 实景三维技术是一种集成了遥…...

Science Robotics 通过新材料打造FiBa软机器人 可实现四种形态进化

近几年由于材料科学的进步&#xff0c;软机器人相关技术近几年研究成果显著&#xff0c;与传统的刚性机器人相比&#xff0c;软机器人的设计灵感来源于自然界中的生物系统&#xff0c;如蠕虫、章鱼、壁虎和青蛙等。这些生物利用柔软、有弹性的材料&#xff0c;在复杂环境中展现…...

C++ 的特性可以不用在主函数中调用

写完代码,都找不到从哪里进去...

香港大学神作 LightRAG 横空出世!AI 检索生成系统革命,秒懂复杂信息,动态数据无所遁形!

❤️ 如果你也关注大模型与 AI 的发展现状&#xff0c;且对大模型应用开发非常感兴趣&#xff0c;我会快速跟你分享最新的感兴趣的 AI 应用和热点信息&#xff0c;也会不定期分享自己的想法和开源实例&#xff0c;欢迎关注我哦&#xff01; 微信订阅号&#xff5c;搜一搜&…...

云栖实录 | 智能运维年度重磅发布及大模型实践解读

本文根据2024云栖大会实录整理而成&#xff0c;演讲信息如下&#xff1a; 演讲人&#xff1a; 钟炯恩 | 阿里云智能集团运维专家 张颖莹 | 阿里云智能集团算法专家 活动&#xff1a; 2024 云栖大会 AI 可观测专场 -智能运维&#xff1a;云原生大规模集群GitOps实践 2024 …...

Vue3中防止按钮重复点击的方式

本文列两种方式&#xff0c;推荐第一种&#xff0c;经过长时间测试第二种防止的还是会漏&#xff0c;这里也列一下 ①使用定时器&#xff08;推荐&#xff09; 判断3秒钟之内方法只能执行一次 <el-button click"handleClick" type"primary" :loading…...

windows主机重新安装zabbix agent提示please clear the previous agent registration

目录 1. Zabbix Agent1.1 错误提示 2. 解决方法2.1 管理员运行cmd2.2 可以正常安装 1. Zabbix Agent 1.1 错误提示 2. 解决方法 2.1 管理员运行cmd 输入 sc.exe delete “Zabbix Agent” 或者 sc.exe delete “Zabbix Agent 2” 如果成功会出现“[SC] DeleteService SUCCES…...

一个将.Geojson文件转成shapefile和kml文件的在线页面工具

最近需要读取.geojson格式的流域边界文件。在谷歌地球桌面版和globalMapper中均无法正常读取。下面我发现的一个在线的平台可以很好实现这一功能。 GeoJSON to SHP Converter Online - MyGeodata Cloud ❤️欢迎点赞收藏❤️...

Mamba学习笔记(1)——原理基础

文章目录 Mamba: Linear-Time Sequence Modeling with Selective State Spaces0 Abstract1 Introduction2 State Space Models3 Selective State Space Models3.1 Motivation: Selection as a Means of Compression3.2 Improving SSMs with Selection3.3 Efficient Implementat…...

后进先出(LIFO)详解

LIFO 是 Last In, First Out 的缩写&#xff0c;中文译为后进先出。这是一种数据结构的工作原则&#xff0c;类似于一摞盘子或一叠书本&#xff1a; 最后放进去的元素最先出来 -想象往筒状容器里放盘子&#xff1a; &#xff08;1&#xff09;你放进的最后一个盘子&#xff08…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互

引擎版本&#xff1a; 3.8.1 语言&#xff1a; JavaScript/TypeScript、C、Java 环境&#xff1a;Window 参考&#xff1a;Java原生反射机制 您好&#xff0c;我是鹤九日&#xff01; 回顾 在上篇文章中&#xff1a;CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

高危文件识别的常用算法:原理、应用与企业场景

高危文件识别的常用算法&#xff1a;原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件&#xff0c;如包含恶意代码、敏感数据或欺诈内容的文档&#xff0c;在企业协同办公环境中&#xff08;如Teams、Google Workspace&#xff09;尤为重要。结合大模型技术&…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

力扣-35.搜索插入位置

题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...

2025季度云服务器排行榜

在全球云服务器市场&#xff0c;各厂商的排名和地位并非一成不变&#xff0c;而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势&#xff0c;对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析&#xff1a; 一、全球“三巨头”…...

LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》

这段 Python 代码是一个完整的 知识库数据库操作模块&#xff0c;用于对本地知识库系统中的知识库进行增删改查&#xff08;CRUD&#xff09;操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 &#x1f4d8; 一、整体功能概述 该模块…...