Linux 信号的产生

1. 概念

在Linux系统中,信号是一种进程间通信的机制,它允许操作系统或其他进程向特定进程发送异步通知。我们可以通过命令 kill -l来查看信号的种类:

Linux系统中的信号可以分为两大类:传统信号和实时信号。从上图可以看出它们分为两个区间:[1, 31] 和[34, 64],无32和33号信号,[1, 31] 区间为传统信号共有31种,当进程收到传统信号后,可以自己选择合适的时候处理;[34, 64]为实时信号共有31种,当进程收到实时信号后,立马处理。

以下是一些常见信号的简要说明:

  • SIGINT(2):用户通过Ctrl+C发送的中断信号,通常用于请求进程终止。
  • SIGQUIT(3):用户通过Ctrl+\发送的退出信号,通常用于请求进程终止并生成core dump。
  • SIGABRT(6):通过调用abort()函数产生的信号,用于异常终止程序。
  • SIGFPE(8):发生致命的算术运算错误时产生。
  • SIGKILL(9):用于立即强制终止进程的信号,不能被进程捕获、阻塞或忽略。
  • SIGSEGV(11):试图写入无效内存地址时产生。
  • SIGALRM(14):由alarm()函数设置的计时器到期时产生。
  • SIGSTOP(19):停止进程执行的信号,不能被进程捕获、阻塞或忽略。
  • SIGTSTP(20):由用户通过Ctrl+Z发送的暂停信号,可以被进程捕获和处理。

进程接收到信号后,有三种处理信号的方式:

  1. 忽略此信号
  2. 执行信号的默认处理函数
  3. 执行信号的自定义处理函数,这种方式也称为信号捕捉

前两种均为操作系统自带的方式,我们可以通过 man 7 signal 命令来查看这些处理行为:

  1. Term (Terminate):这是当一个信号没有被处理(即没有安装信号处理函数)时,信号的默认行为,收到信号的进程将被终止。例如,SIGTERM的默认行为是终止进程。

  2. Ign (Ignore):进程可以选择忽略一个信号,这意味着当信号到达时,进程将不会执行任何默认行为或自定义处理函数。

  3. Core:指的是在进程终止时生成core dump的行为。当进程因为某些信号(如SIGSEGV)而终止时,如果设置了对应的信号行为为core,系统将生成该进程在终止瞬间的内存快照,以便于后续的错误分析。

  4. Stop:指的是信号的默认行为或自定义动作是停止进程的执行。例如,SIGSTOP信号会使进程停止,且不能被进程捕获或忽略。其他可停止信号(如SIGTSTP)可以被进程捕获和处理。

  5. Cont (Continue):指当一个已停止的进程接收到继续信号(如SIGCONT)时,将恢复执行。进程从停止状态恢复到运行状态。

我们继续往下翻可以看到各种信号对应的默认行为。

接下来我们来介绍第三种信号处理的方式,即信号捕捉。需要使用到 signal 函数。signal 函数是C语言标准库中的一个函数,用于设置信号处理程序,当程序运行时接收到特定的信号,signal 函数允许开发者定义一个函数来响应这些信号。

其中,signum参数指定了要处理的信号编号,handler参数是一个指向信号处理函数的指针,该函数指针类型为 void (*)(int)。如果 handlerSIG_IGN,则信号将被忽略;如果为 SIG_DFL,则信号将采用默认的操作系统行为。

#include<iostream>
#include<signal.h>
using namespace std;
void handler(int signum)
{cout<<"received signal: "<<signum<< endl;
}
int main()
{signal(2,handler);while(1){cout<<"waiting for signal..."<<endl;sleep(1);}return 0;
}

以上代码中,我们通过 signal(2, handler) 把2号信号的处理方式变成了执行函数handler。而从上文介绍我们了解到从键盘上按下 ctrl + C 可以发送2号SIGINT信号。

可以看到按下ctrl + C后,本来是发送2号信号时会直接终止进程,但修改处理行为后,现在输出receive signal: 2了。

3. 注意
1. ctrl +  C  产生的信号只能发给前台进程。一个命令后面加个&可以放到后台运行 , 这样 Shell 不必等待进程结束就可以接受新的命令, 启动新的进程。
2. Shell 可以同时运行一个前台进程和任意多个后台进程 , 只有前台进程才能接到像 ctrl +  C 这种控制键产生的信号。
3. 前台进程在运行过程中用户随时可能按下 Ctrl - C 而产生一个信号 , 也就是说该进程的用户空间代码执行到任何地方都有可能收到 SIGINT 信号而终止 , 所以信号相对于进程的控制流程来说是异步
(Asynchronous) 的。

2. 产生

信号可以由多种方式产生,包括硬件产生和软件产生。

软件产生

软件产生的信号指的是由进程自身或其他进程产生的信号,其可以通过系统调用实现,常用的系统调用包括 kill()raise()abort()alarm()

kill

kill函数是在Unix和类Unix系统中,包括Linux,用于向进程发送信号的系统调用。这个函数允许一个进程请求操作系统向另一个进程发送指定的信号,从而可以控制目标进程的行为,如终止进程、请求进程停止或继续执行等。

参数:

  • pid:目标进程的进程ID。如果pid为正数,则信号发送给指定的进程;如果pid为0,则信号发送给调用进程所属的进程组。
  • sig:准备发送的信号码。如果sig为0,则不发送信号,但会执行错误检查,通常用于检测目标进程是否存在。

返回值:

  • 返回0:发送信号成功
  • 返回-1:发送信号失败

void handler(int signum)
{cout<<"received signal: "<<signum<< endl;exit(1);
}
int main()
{pid_t pid = fork();if(pid == 0)//child{signal(2,handler);while(1){cout<<"child process waiting for signal..."<<endl;sleep(1);}}sleep(5);kill(pid,2);//send signal to child processreturn 0;
}

代码示例如上,子进程等待信号,5秒后,父进程向子进程发出2号信号,子进程收到该信号并执行handler 函数,最终退出。

同时,我们也可以在 Shell 中使用 kill 命令,如下,其底层为调用 kill接口。

kill -sig pid

raise

参数:

  • sig:要发送的信号的编号

返回值:

  • 返回0:发送信号成功
  • 返回-1:发送信号失败

在Linux系统编程中,raise函数用于给当前进程发送一个信号,这个函数等效于kill(getpid(), sig)raise函数通常用于引发特定的信号处理程序,或者在需要立即响应信号的场景中使用。

void handler(int signum)
{cout << "received signal: " << signum << endl;exit(1);
}
int main()
{signal(2, handler);int cnt = 5;while (cnt--){cout << "waiting for signal,cnt = " << cnt << endl;sleep(1);}raise(2);return 0;
}

代码示例如上,while 循环执行5秒后,进程给自己发出2号信号,进程收到该信号并执行handler 函数,最终退出。

abort

在Linux系统中,abort函数是一个用于立即终止程序执行的系统调用。它不仅终止程序,而且会生成一个core dump(如果系统配置允许),这有助于调试和理解程序崩溃时的状态。

abort函数被调用时,它会向调用进程发送SIGABRT信号,SIGABRT信号的值通常为6。如果这个信号没有被处理,则默认行为是终止进程并生成core dump,以便后续的错误分析。

core dump的概念

接下来我们来了解 core dump 是什么,core dump 是指当Linux或Unix-like系统中的程序因为异常或错误而崩溃时,操作系统会生成的一个包含了程序崩溃时内存映像的文件。这个文件通常包含了程序的寄存器状态、堆栈信息、内存管理信息等,可以用于调试目的,帮助开发者分析程序崩溃的原因。

代码示例:

int Div(int a, int b)
{if (b == 0)abort();return a / b;
}
int main()
{int a = 5, b = 0;cout << Div(a, b);return 0;
}

上述代码发生了除0错误,进而调用了 abort 函数,可我们并没有看到在当前目录下生成的core dump文件,这是因为生成core dump文件是要有条件的。

core dump文件的生成条件

core dump文件的生成不是自动的,它依赖于几个条件:

  • 当前用户的 ulimit -c+n(单位为byte) 设置必须允许生成core文件,或者设置为 ulimit -c unlimited 以移除大小限制。

  • 程序必须有权限在其当前工作目录中创建文件。

我们可以使用 ulimit -a 命令显示当前的所有资源限制。

我们可以看到 core file size 为 0,即当前我们不能创建core file,我们需要使用ulimit -c 命令设置core file size的大小进而能创建core file。

core dump文件的作用

core dump文件对于软件开发和维护至关重要,因为它们提供了程序崩溃时的详细快照。通过使用调试工具(如GDB)分析​​​​​​​core dump文件,开发者可以追溯程序崩溃时的函数调用堆栈,检查变量的状态,从而定位到导致崩溃的代码行和潜在的错误。

alarm

alarm函数用于设置一个定时器,该定时器会在指定的秒数后向进程发送SIGALRM信号(14)。

参数:

  • seconds:在seconds秒后发送信号

返回值:

  • 如果之前有还没响的闹钟:取消上一次的闹钟,并返回上一次闹钟的剩余秒数
  • 如果之前没有闹钟了:返回0

硬件产生

硬件产生的信号通常是由于用户输入或系统异常触发的。例如,当用户在终端上按下组合键如Ctrl+C时,会产生SIGINT信号,用于中断当前运行的进程。此外,硬件异常,如非法内存访问,也会导致内核生成相应的信号并发送给发生事件的进程。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/54237.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

htop(1) command

文章目录 1.简介2.格式3.选项4.交互式命令5.示例6.小结参考文献 1.简介 htop 是一种交互式、跨平台的基于 ncurses 的进程查看器。 类似于 top&#xff0c;但 htop 允许您垂直和水平滚动&#xff0c;并使用指向设备(鼠标)进行交互。您可以观察系统上运行的所有进程&#xff0…

24年蓝桥杯及攻防世界赛题-MISC-2

11 Railfence fliglifcpooaae_hgggrnee_o{cr} 随波逐流编码工具 分为5栏时,解密结果为:flag{railfence_cipher_gogogo} 12 Caesar rxms{kag_tmhq_xqmdzqp_omqemd_qzodkbfuaz} mode1 #12: flag{you_have_learned_caesar_encryption} 随波逐流编码工具 13 base64 base64解…

iOS17找不到developer mode

iOS17找不到开发者模式 developer mode 下载过app之后、弹窗Developer Mode Required之后&#xff0c;这个菜单就出现了&#xff08;之前死活找不到&#xff09;。 背景&#xff1a;用蒲公英分发测试app&#xff0c;有个同事买了新机(iphone 15 pro max)&#xff0c;添加了白名…

ppt一键生成免费版软件有哪些?如何高效生成论文答辩?

答辩经验丰富的人都知道&#xff0c;制作论文答辩ppt是一项既繁琐又耗时的工作。 我们需要从数万字的论文中提炼关键点&#xff0c;梳理内容的逻辑关系&#xff0c;然后进行细致的排版和美化&#xff0c;最后还要进行反复的检查和试讲。整个过程不仅耗费时间&#xff0c;而且需…

硬件工程师笔试面试——变压器

目录 9、变压器 9.1 基础 变压器原理图 变压器实物图 9.1.1 概念 9.1.2 变压器组成结构 9.1.3 变压器原理 9.1.4 变压器的类型 9.1.5 应用领域 9.2 相关问题 9.2.1 变压器的工作原理是什么? 9.2.2 如何选择合适的变压器类型? 9.2.3 变压器在实际应用中,如何进行…

8.1差分边缘检测

基本概念 差分边缘检测是一种图像处理技术&#xff0c;用于检测图像中的边缘。边缘是指图像中灰度值发生显著变化的区域。差分边缘检测通常通过计算图像的梯度来实现&#xff0c;梯度反映了灰度值的变化率。在OpenCV中&#xff0c;可以使用不同的算子来检测不同方向的边缘&…

[docker]入门

本文章主要讲述的是&#xff0c;docker基本实现原理&#xff0c;docker概念的解释&#xff0c;docker的使用场景以及docker打包与部署的应用。 文章中docker所运行的系统&#xff1a;CentOS Linux release 7.9.2009 (Core) 目录 docker是什么&#xff0c;什么时候需要去使用 …

【Git原理与使用】版本管理与分支管理(1)

目录 一、基本操作 1、初识Git 2、Git安装[Linux-centos] 3、Git安装[ Linnx-ubuntu] 4、创建git本地仓库 5、配置Git 6、认识工作区、暂存区、版本库 7、添加文件 8、查看历史提交记录 9、查看.git文件目录结构 10、查看版本库对象的内容 11、小结&#xff08;在本地的.git仓库…

回归预测|基于饥饿游戏搜索优化随机森林的数据回归预测Matlab程序HGS-RF 多特征输入单输出 高引用先用先创新

回归预测|基于饥饿游戏搜索优化随机森林的数据回归预测Matlab程序HGS-RF 多特征输入单输出 高引用先用先创新 文章目录 一、基本原理1. 饥饿游戏搜索优化算法&#xff08;HGS&#xff09;简介2. 随机森林&#xff08;RF&#xff09;简介3. HGS-RF回归预测流程1. 初始化2. 随机森…

基于SpringBoot+Vue+MySQL的在线宠物用品商城销售系统

系统展示 用户前台界面 管理员后台界面 系统背景 随着人们生活质量的提升和宠物经济的蓬勃发展&#xff0c;宠物已成为众多家庭不可或缺的一员。宠物市场的需求日益增长&#xff0c;涵盖了食品、用品、医疗、美容等多个领域。基于SpringBootVueMySQL的在线宠物用品商城销售系统…

新发布的OpenAI o1生成式AI模型在强化学习方面迈出了重要的一步

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

【Unity杂谈】iOS 18中文字体显示问题的调查

一、问题现象 最近苹果iOS 18系统正式版推送&#xff0c;周围升级系统的同事越来越多&#xff0c;有些同事发现&#xff0c;iOS 18上很多游戏&#xff08;尤其是海外游戏&#xff09;的中文版&#xff0c;显示的字很奇怪&#xff0c;就像一些字被“吞掉了”&#xff0c;无法显示…

考研数据结构——C语言实现无向图邻接矩阵

首先&#xff0c;定义了一些基本的数据结构和常量&#xff1a; VertexType 和 EdgeType 分别用于表示图中的顶点和边的权重。MAXVEX 定义了图中最大顶点数为100。INFINITY 用于表示顶点之间没有直接的边相连&#xff0c;这里用65535作为无穷大的表示。 定义了一个图的结构体 MG…

MiniCPM3-4B | 笔记本电脑运行端侧大模型OpenBMB/MiniCPM3-4B-GPTQ-Int4量化版 | PyCharm环境

MiniCPM3-4B&#xff0c;轻松在笔记本电脑上运行大模型&#xff1f; 背景一、选择模型二、模型下载三、模型运行四、总结 背景 2024年9月5日&#xff0c;面壁智能发布了MiniCPM3-4B&#xff0c;面壁的测试结果声称MiniCPM3-4B表现超越 Phi-3.5-mini-instruct 和 GPT-3.5-Turbo-…

卸载完mathtype后,删除word加载项中的mathtype

请参考博客“卸载完mathtype后&#xff0c;word加载项中还是有mathtype的解决方法_怎么删除word加载项里的mathtype-CSDN博客”以及 “安装卸载MathType经验解决MathType DLL找不到的问题——超实用_mathtype dll cannot-CSDN博客” 如果在删除.dotm文件时&#xff0c;删不掉…

随着访问范围的扩大 OpenAI o1-mini 现已向免费用户开放

上周&#xff0c;OpenAI 展示了其最新的大型语言模型&#xff08;LLM&#xff09;–OpenAI o1及其小兄弟 OpenAI o1-mini。该公司在公告中称&#xff0c;Plus 和 Team 用户可在公告发布之日起访问该模型。企业和教育用户将在本周获得该模型&#xff0c;而免费用户最终将获得 o1…

Golang | Leetcode Golang题解之第404题左叶子之和

题目&#xff1a; 题解&#xff1a; func isLeafNode(node *TreeNode) bool {return node.Left nil && node.Right nil }func sumOfLeftLeaves(root *TreeNode) (ans int) {if root nil {return}q : []*TreeNode{root}for len(q) > 0 {node : q[0]q q[1:]if no…

Mac 上,终端如何开启 proxy

前提 确保你的浏览器可以访问 google&#xff0c;就是得先有这个能力 步骤 查看网络的 http/https 还有 socks5 的 port配置 .zshrc 查看 port 点击 wifi 设置 以我的为例&#xff0c;我的 http/https 都是 7890&#xff0c; socks5 是 7891 查看代理的port 以我的软件…

清华团队发布鼻咽癌诊断模型,自动从HE染色图像生成EBER染色图像|文献精析·24-09-18

小罗碎碎念 今天精读的这篇文章于2024年7月22日发表&#xff0c;作者来自清华大学和广西大学。 角色姓名单位名称&#xff08;中文&#xff09;第一作者曾清华大学珠三角研究院医学光学技术研发中心&#xff0c;广州通讯作者何清华大学深圳国际研究生院生物制药与健康工程研究所…

【Django5】django的helloworld

安装django pip install djangoDjango官方中文文档 https://docs.djangoproject.com/zh-hans/5.1/Github链接 https://github.com/django/django创建Django项目 cd到想要创建项目的文件夹下&#xff0c;输入以下命令创建项目 这行代码将会在当前目录下创建一个 mysite 目录 …