【Linux】:信号与信号产生

朋友们、伙计们,我们又见面了,本期来给大家带来信号和信号的产生相关代码和知识点,如果看完之后对你有一定的启发,那么请留下你的三连,祝大家心想事成!

C 语 言 专 栏:C语言:从入门到精通

数据结构专栏:数据结构

个  人  主  页 :stackY、

C + + 专 栏   :C++

Linux 专 栏  :Linux

目录

1. 信号概念

2. 信号的产生

① 前台进程

② 后台进程

2.1 信号的产生方式

① 通过键盘产生

② 通过系统调用产生 

③ 通过硬件异常产生 

④ 通过软件条件产生

3. 核心转储(core dump) 


1. 信号概念

从生活的角度来说:

道路边的红绿灯信号、上下课的铃声、古时候的狼烟、旗语、手机的来电铃声等等;

当这些信号出现的时候我们可以识别并下意识的做出对应的反应。

在Linux角度来说:

在命令行输入kill -l就可以查看系统可支持的信号列表;

当我们程序运行起来,我们直接使用Ctrl + c 就可以终止进程,这也叫做信号。

  • ① 信号没有产生的时候,其实我们已经知道怎么来处理这个信号;
  • ② 信号什么时候来,我们并不清楚,信号的到来相对于我目前做的工作来说是异步产生的;
  • ③ 信号产生了,我们不一定要立即处理他,而是等到合适的时机来处理;
  • ④ 信号到来到我要处理信号的期间,我们需要对已经到来的信号进行暂时保存。

信号是向目标进程发送通知消息的一种机制。 

2. 信号的产生

在谈论信号的产生之前先来了解一下Linux中的前、后台进程:

① 前台进程

在命令行中我们输入./exe启动一个进程时启动的是前台进程;

我们自己的程序以前台进程的方式运行,此时我们输入指令时是没有任何效果的!

shell也是一个进程,我们使用命令行时使用的就是shell这个前台进程,所以当使用./exe运行程序时,OS就会自动将shell放到后台,前台进程只能有一个。

一般情况下:Ctrl + c 终止前台进程

Ctrl + \ :终止前台进程

② 后台进程

在命令行输入./exe & 以后台程序的方式运行;

后台进程可以有多个,使用 jobs命令查看所有的后台进程:

使用 fg 任务编号:将指定的后台进程提到前台

前台进程不能被暂停,如果我们正常运行起来的前台进程使用Ctrl + z时暂停,会将该进程必须放到后台;

使用bg 任务编号:将指定后台进程运行起来。

2.1 信号的产生方式

在命令行输入kill -l可以查看所有信号;

没有0号信号,因为在我们程序运行结束之后,成功返回的是0。

信号有对应的编号和名称,我们既可以使用编号又可以使用名称。

1 ~ 31叫做普通信号,34 ~ 64叫做实时信号。

向目标进程发送信号时,对于普通信号来讲,该进程如何知道自己是否收到某种信号?

在进程的PCB中维护一张位图,并且每个进程都有一张函数指针数组表,数组下标和信号编号强相关;

位图中比特位的位置决定信号的编号;

           比特位的内容决定是否收到该信号。

当进程收到指定信号时,先去位图中查找对应的信号,然后通过信号编号在函数指针数组中执行对应的方法。

因为OS是进程的管理者,无论信号的产生方式有多少种,永远只能由OS向目标进程发送。

发信号其实是向位图中写入(对对应的比特位操作) 

信号的本质:用软件来模拟硬件与CPU之间的中断行为!

① 通过键盘产生

我们在命令行./exe运行起来的进程,当我们在键盘上敲下Ctrl + c组合键时,该进程就会被终止,此时我们从键盘上输入Ctrl + c就是向该进程发送指定的信号。

在合适的时候处理信号的有三种情况:

  • 1. 信号的默认行为
  • 2. 忽略该信号
  • 3. 自定义行为(信号的捕捉)

signal接口可以用于捕捉信号去执行自定义函数方法:

我们输入的Ctrl + c其实是2号信号,输入的Ctrl + z其实是20号信号,输入的Ctrl + /其实是3号信号,接下来我们可以采用信号捕捉的方式来验证一下:

#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
using namespace std;// 自定义行为的函数返回值必须是void,参数必须是int类型
void handler(int signo)
{while (true){std::cout << "这是一个" << signo << "号信号" << std::endl;sleep(1);}
}int main()
{signal(2, handler); // 捕捉2号信号signal(3, handler); // 捕捉3号信号signal(20, handler);// 捕捉20号信号while (1){cout << "running ...., pid: " << getpid() <<endl;sleep(1);}return 0;
}

9号信号不可被捕捉,即便是我们使用signal接口进行捕捉,也不能让9号信号执行自定义方法!

② 通过系统调用产生 

kill接口:向指定进程发送指定的信号

让我们自己的进程运行5s,然后使用kill系统调用来发送2号信号;

#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
using namespace std;void handler(int signo)
{while (true){std::cout << "这是一个" << signo << "号信号" << std::endl;sleep(1);}
}int main()
{signal(2, handler); // 捕捉2号信号int cnt = 5;while (cnt--){cout << "running ...., pid: " << getpid() << endl;sleep(1);}// kill(getpid(), SIGINT); // 系统调用接口产生信号kill(getpid(), 2);return 0;
}

raise接口:自己给自己发送指定的信号

#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
using namespace std;// 自定义行为的函数返回值必须是void,参数必须是int类型
void handler(int signo)
{while (true){std::cout << "这是一个" << signo << "号信号" << std::endl;sleep(1);}
}int main()
{signal(3, handler); int cnt = 5;while (cnt--){cout << "running ...., pid: " << getpid() << endl;sleep(1);}// 给自己发送3号信号raise(SIGQUIT);return 0;
}

abort接口:使当前进程收到信号并异常终止

#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
using namespace std;// 自定义行为的函数返回值必须是void,参数必须是int类型
void handler(int signo)
{while (true){std::cout << "这是一个" << signo << "号信号" << std::endl;sleep(1);}
}int main()
{signal(6, handler); // 捕捉2号信号int cnt = 5;while (cnt--){cout << "running ...., pid: " << getpid() << endl;sleep(1);}abort(); // 收到6号信号return 0;
}

③ 通过硬件异常产生 

异常产生的信号比如常见的段错误、野指针问题;

在这里演示一下常见的除0错误产生的信号:

当发生除0异常时,OS直接向进程发生8号信号来终止进程。

接下来我们捕捉一下8号信号看看会发生什么:

#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
using namespace std;void handler(int signo)
{// 注意这里没有循环std::cout << "这是一个" << signo << "号信号" << std::endl;sleep(1);
}int main()
{signal(8, handler); // 捕捉8号信号int a = 10;a /= 0;return 0;
}

我们捕捉信号执行的自定义函数没有循环,为什么在结果中会循环打印呢?

当发生除0错误时,CPU内部的状态寄存器(硬件资源)中的溢出标记位会置为1,此时OS就会检测到,并把其解释为kill(targetprocess, SIGFPE)函数调用,就会终止进程,但是我们将SIGFPE进行捕捉之后去执行对应的自定义方法,并没有终止该进程,所以CPU会一直调度该进程,当遇到除0异常时又继续执行我们实现的自定义函数。

当发生一些野指针和越界访问时,此时从由虚拟到物理映射时页表中的MMU硬件单元就会出现异常,就会给进程发送指定信号用来终止进程。

④ 通过软件条件产生

在之前的管道部分就说过,管道的读端关闭,如果写端还是继续写入,OS就会向写端发送SIGPIPE信号来终止写端进程,这就是一种通过软件来产生的信号。

我们可以通过alarm函数来给进程设置一个闹钟,也就是告诉OS在指定时间之后向进程发送SIGALRM信号,默认处理动作是终止当前进程。

alarm接口:

#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
using namespace std;void handler(int signo)
{while (true){std::cout << "这是一个" << signo << "号信号" << std::endl;sleep(1);}
}
int main()
{signal(SIGALRM, handler);// 3秒之后发送信号alarm(3);while (true){cout << "running ...., pid: " << getpid() << endl;sleep(1);}return 0;
}

  • 所有用户的行为都是以进程的形式在操作系统中表现的;
  • 操作系统只要把进程调度好,就能完成所有的用户任务;
  • CMOS时钟会周期性的、高频率的向CPU发送时钟中断;
  • 操作系统的执行是基于硬件中断的!  

3. 核心转储(core dump) 

当进程运行异常时,OS会根据异常信息向进程发送对应的信号使进程终止,并且打印的异常信息也很明确,但是我们如何知道异常出现在程序代码的具体的什么位置呢?

当进程运行发生core异常时,OS会将该进程在内存中发生异常的核心上下文数据转储到磁盘中形成一个以该进程pid和core命名的磁盘文件。

使用命令 ulimit -a:查看core文件的大小

使用命令 ulimit -c 大小:修改core文件的大小

在修改完core文件大小之后出现异常时就会转储到磁盘: 

为什么我们使用的Linux云服务器这个转储的动作默认是关闭的呢?

  • ① 因为发成异常之后形成的core文件太大了;
  • ② 如果异常比较多,磁盘被打满,会直接影响服务器的正常运行。

使用core文件:

朋友们、伙计们,美好的时光总是短暂的,我们本期的的分享就到此结束,欲知后事如何,请听下回分解~,最后看完别忘了留下你们弥足珍贵的三连喔,感谢大家的支持!  

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

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

相关文章

YOLOv10优改系列一:YOLOv10融合C2f_Ghost网络,让YoloV10实现性能的均衡

&#x1f4a5; &#x1f4a5;&#x1f4a5; &#x1f4a5;&#x1f4a5; &#x1f4a5;&#x1f4a5; &#x1f4a5;&#x1f4a5;神经网络专栏改进完整目录&#xff1a;点击 &#x1f497; 只需订阅一个专栏即可享用所有网络改进内容&#xff0c;每周定时更新 文章内容&#x…

微信自动通过好友和自动拉人进群,微加机器人这个功能太好用了

又发现一个好用的功能&#xff0c;之前就想找一个这种工具&#xff0c;现在发现可以利用微加机器人的两个功能来实现&#xff0c;分别是加好友和关键词拉群 首先 微加机器人的专业版 > 功能 > 加好友设置 可以设置一个关键词通过,这样别人加好友的时候只需要输入制定内…

实战案例(5)防火墙通过跨三层MAC识别功能控制三层核心下面的终端

如果网关是在核心设备上面&#xff0c;还能用MAC地址进行控制吗&#xff1f; 办公区域的网段都在三层上面&#xff0c;防火墙还能基于MAC来控制吗&#xff1f; 采用正常配置模式的步骤与思路 &#xff08;1&#xff09;配置思路与上面一样 &#xff08;2&#xff09;与上面区…

通信工程学习:什么是PDF策略决策功能

PDF策略决策功能 PDF策略决策功能&#xff08;Policy Decision Function, PDF&#xff09;在通信网络中&#xff0c;特别是在IP多媒体子系统&#xff08;IMS&#xff09;中&#xff0c;扮演着至关重要的角色。以下是对PDF策略决策功能的详细解释&#xff1a; 一、定义与功能概…

CentOS Stream 8中安装和使用 Docker

docker安装包-CSDN博客 〇、常用的docker命令 docker的作用&#xff1a; 快速进行软件的安装&#xff0c;便于软件环境的维护 docker的镜像: 压缩了指定软件的安装包的文件。使用镜像文件创建容器 docker的容器: 容器可以理解为就是一台小电脑。安装的linux系统&am…

【F的领地】项目拆解:小学教辅资料

项目介绍 虚拟资料项目的赛道其实一直可以做&#xff0c;实际上就是一个信息差项目。 知识付费是常青树&#xff0c;人天生有为知识付费的倾向。 而且虚拟资料通常一份 19~99 的资料有这方面需求很容易就能付款。 主要是产附属的流量再提问题。 我有个同乡&#xff0c;18年…

CircleProgressView 鸿蒙ArkTS自定义View实现圆形进度条

上篇的截图中除了一个上下的箭头&#xff0c;还有一个圆形进度条&#xff0c;今天我们来讲讲这个如何进行实现 我们看这个图形的构造&#xff0c;其实很简单&#xff1a;一个圆形图形&#xff0c;以及一个文本来显示进度 所以我们用一个层叠布局 绘制一个带颜色的圆形&#xff…

Java设计模式—面向对象设计原则(一) ----->开闭原则OCP(完整详解,附有代码+案例)

3.1开闭原则 对扩展开放&#xff0c;对修改关闭。在程序需要进行拓展的时候&#xff0c;不能去修改原有的代码&#xff0c;实现一个热插拔的效果。简言之&#xff0c;是为了使程序的扩展性好&#xff0c;易于维护和升级。想要达到这样的效果&#xff0c;我们需要使用接口和抽象…

怎么选择靠谱AI论文生成工具?看完我的试用都会明白!

2024年上半年开始AI论文写作工具开始火了&#xff0c;层出不穷&#xff01;作为一个经常需要写论文的懒人&#xff0c;我非常好奇这些AI工具的实际效果到底怎么样&#xff1f;为了测试不同工具的实力&#xff0c;我对他们都进行了试用&#xff0c;发现了一些意想不到的结果....…

路由器的固定ip地址是啥意思?固定ip地址有什么好处

‌在当今数字化时代&#xff0c;‌路由器作为连接互联网的重要设备&#xff0c;‌扮演着举足轻重的角色。‌其中&#xff0c;‌路由器的固定IP地址是一个常被提及但可能让人困惑的概念。‌下面跟着虎观代理小二一起将深入探讨路由器的固定IP地址的含义&#xff0c;‌揭示其背后…

QML入门之创建可重用的组件(一)

我们在日常开发中都会封装一些组件以便于项目内重复利用。QML创建可重用组件一般有两种方法。 自定义Item使用Component创建自定义组件 自定义Item 以一个自定义按钮举例&#xff1a; import QtQuick 2.12Rectangle {id: root// 自定义属性property string btnDis: qsTr(&qu…

51单片机+proteus仿真+基本实验学习1(跑马灯、独立按键和数码管)

目录 1.实验一跑马灯 1.1代码的生成 1.1.151单片机的延时函数的生成 1.1.251单片机的流水灯代码编写 1.2仿真框图 2.实验二I/O独立按键 2.1基本概念 2.1.1按键所需的基本知识 2.2代码的生成 2.2.1头文件定义的代码 2.2.2 执行代码 2.3仿真图 ​3实验三数码管 3.1基…

基于Verilog HDL的FPGA设计基础

第一章 Verilog数字集成电路设计方法概述 HDL(Hardware Description Language)----硬件描述语言 EDA(Electronic Design Automation)----电子设计自动化 VLSI(Very Large Scale Integrated)----超大规模集成电路 ASIC(Application Specific Integrated Circuit)----专用集成电路…

Unity射击游戏开发教程:(35)轰炸敌人

现在敌人和飞机已经慢慢地越来越有各自地地行为了,在本文中,我们将介绍如何创建一个具有以下行为的敌人: 飞机会来回弹跳。飞机将有 4 架无人机轰炸机围绕飞机旋转。无人机轰炸机会偶尔投下沿着屏幕传播的炸弹。如果炸弹击中玩家或在随机时间后就会爆炸。如果炸弹没有击中玩…

macOS上谷歌浏览器的十大隐藏功能

谷歌浏览器&#xff08;Google Chrome&#xff09;在macOS上拥有一系列强大而隐蔽的特性&#xff0c;这些功能能显著提高您的浏览体验。从多设备同步到提升安全性和效率&#xff0c;这些被低估的功能等待着被发掘。我们将逐步探索这些功能&#xff0c;帮助您最大化利用谷歌浏览…

数据分析-螺旋环状气泡图

1 原理 采用阿基米德螺线原理&#xff0c;即以一个点匀速离开一个固定点的同时又以固定的角速度绕该固定点转动而产生的轨迹。具体原理见&#xff1a;阿基米德螺线。坐标轴公式为&#xff1a; 其中x为横坐标&#xff0c;y为纵坐标&#xff0c;r为离中心点的半径&#xff0c;为坐…

CSS之我不会

非常推荐html-css学习视频&#xff1a;尚硅谷html-css 一、选择器 作用&#xff1a;选择页面上的某一个后者某一类元素 基本选择器 1.标签选择器 格式&#xff1a;标签{} <h1>666</h1><style>h1{css语法} </style>2.类选择器 格式&#xff1a;.类…

PFC理论基础与Matlab仿真模型学习笔记(1)--PFC电路概述

一、整流器滤波电路简介 整流器滤波电路的主要功能是将交流电&#xff08;AC&#xff09;转换为直流电&#xff08;DC&#xff09;&#xff0c;并通过滤波器减少波动以输出稳定的直流电。其工作原理主要分为两个部分&#xff1a; 1.整流部分 整流器的核心器件是二极管&#…

JDBC API详解一

DriverManager 驱动管理类&#xff0c;作用&#xff1a;1&#xff0c;注册驱动&#xff1b;2&#xff0c;获取数据库连接 1&#xff0c;注册驱动 Class.forName("com.mysql.cj.jdbc.Driver"); 查看Driver类源码 static{try{DriverManager.registerDriver(newDrive…

基于SpringBoot的扶贫助农管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 基于JavaSpringBootVueMySQL的扶贫助农管理系统【附源码文档…