【Linux系统化学习】信号概念和信号的产生

目录

信号的概念

从生活中的例子中感知信号

前台进程和后台进程

前台进程

后台进程

操作系统如何知道用户向键盘写入数据了?

进程如何得知自己收到了信号?

信号捕捉

signal函数

Core Dump(核心转储)

信号产生的方式

通过键盘按键产生信号

kill函数

raise函数

硬件异常产生信号

浮点数异常

非法地址异常 

由软件条件产生信号

alarm函数


信号的概念

从生活中的例子中感知信号

  1. 你在网上买了很多件商品,再等待不同商品快递的到来。但即便快递没有到来,你也知道快递来临时,你该怎么处理快递。也就是你能“识别快递”
  2. 当快递员到了你楼下,你也收到快递到来的通知,但是你正在打游戏,需5min之后才能去取快递。那么在在这5min之内,你并没有下去去取快递,但是你是知道有快递到来了。也就是取快递的行为并不是一定要立即执行,可以理解成“在合适的时候去取”。
  3. 在收到通知,再到你拿到快递期间,是有一个时间窗口的,在这段时间,你并没有拿到快递,但是你知道有一个快递已经来了。本质上是你“记住了有一个快递要去取”
  4. 当你时间合适,顺利拿到快递之后,就要开始处理快递了。而处理快递一般方式有三种:1. 执行默认动作(幸福的打开快递,使用商品)2. 执行自定义动作(快递是零食,你要送给你你的女朋友)3. 忽略快递(快递拿上来之后,扔掉床头,继续开一把游戏)
  5. 快递到来的整个过程,对你来讲是异步的,你不能准确断定快递员什么时候给你打电话

通过上面的例子我们可以总结出来一下四点:

  • 信号没有产生的时候,其实我们已经直到怎么处理这个信号了。
  • 信号的到来我们并不清楚具体什么时候,信号的到来对于我正在做的工作是异步产生的。
  • 信号产生了,我们不一定要立即处理它,而是我们在合适的时候处理。
  • 我们有一种能力,可以将已经到来的信号进行暂时保存。

让我们转换视角,将我们看成操作系统中被操作系统管理的进程;在进程运行期间根本不知道操作系统什么时候会给这个进程传递一种信息,当操作系统的信息来临时进程可以选择直接处理这个信息,也可以将信息暂时保存下来。

到此我们可以给信号下个定义信号是一种向目标进程发送通知消息的一种机制

在了解信号的产生之前我们还需要一点预备知识让我们对操作系统的信号机制了解的更全面一点。


前台进程和后台进程

前台进程

当我们循环执行一条输出语句时,执行我们的Linux指令操作系统是没有任何相应的;也就是操作系统没有能力接受用户的输入

后台进程

只需要在运行可执行程序时指令的后面添加一个按位与的位运算符即可成为后台进程。后台进程有能力可以接受用户的输入,当我么输入指令后shell会执行我们的命令。

查看后台进程:

jobs

将后台进程调整为前台进程:

fg number(后台每个进程的任务号)

将前台进程调整为后台进程

ctrl + z
//先对前台进程进行暂停
bg number
//然后在进行调整

总结: 

  1. 前台进程有且只有一个,一般情况下为shell。
  2. 操作系统会自动将shell提到前台或者后台。
  3. 前台进程可以被ctrl+c终止掉。
  4. 前台进程不可以被暂停,如果被暂停该前台进程必须被放到后台。 

操作系统如何知道用户向键盘写入数据了?

操作系统是管理者,键盘、显示器、网卡等这些硬件也是要被操作系统管理起来的。当我们使用键盘进行写入操作时,键盘文件会发生变化;操作系统会将这些输入的数据进行各种处理。但是根据冯诺依曼体系结构外设是不可以和CPU进行打交道的,可以通过其他硬件间接联系。CPU中含有很多针脚,外设通过8259主板和CPU上的针脚关联。每个针脚对应一个外设,当我们键盘进行写入时,高低电平会通过主板让针脚发生“变化”。这样CPU就可以知道键盘进行写入了然后读取数据,对数据进行处理。这样的方式称作中断,引起中断的原因称作中断源。对于CPU上的针脚,操作系统也是需要进行管理的,使用一个函数指针数组;数组中的指针指向该针脚对应外设的读写操作函数。这个函数指针数组被称为断向量表。

因此信号的本质就是使用软件来模拟中断的行为。


进程如何得知自己收到了信号?

前面的文章中我们简单提到过信号系统中总共含有62中信号;其中 1-31为普通信号,34-64为实时信号,且没有0号信号。这篇文章我们只探讨普通信号,不对实时信号做任何解释和介绍。

可以使用kill -l查看系统信号

每个信号都含有一个数字编号和一个宏定义名称,这些宏定义可以在signal.h中找到,例如其中有定 义 #define SIGINT 2。

前面的文章我们介绍了每个进程都会被操作系统管理起来,形成一个结构体(PCB)其中含有进程的属性和信息;在这个结构体中就含有一个信号位图,每个比特位代表对应的信号每个比特位对应的内容表示是否收到了信号。当进程收到信号之后,会修改这个信号位图表示收到了某中信号。


信号捕捉

上面提到每个信号都有编号和宏定义,当进程收到某种信号时会调用系统默认的方法;Linux操作系统支持我们使用函数将默认方法改写。

signal函数

//头文件
#include<signal.h>
//函数名称
signal(signo,(void)(*)(int))
  • 第一个参数表示我们要对哪个信号进行捕捉。
  • 第二个参数是一个参数为整形的函数指针,指向我们重写的函数;这个函数的参数也为我们的第一个参数。

注意:对于9号进程来说是不可以被重写函数的。


Core Dump(核心转储)

首先解释什么是Core Dump。当一个进程要异常终止时,可以选择把进程的用户空间内存数据全部 保存到磁盘上,文件名通常是core,这叫做Core Dump。进程异常终止通常是因为有Bug,比如非法内存访问导致段错误,事后可以用调试器检查core文件以查清错误原因,这叫做Post-mortem Debug(事后调试)。一个进程允许产生多大的core文件取决于进程的Resource Limit(这个信息保存 在PCB中)。默认是不允许产生core文件的,因为core文件中可能包含用户密码等敏感信息,不安全。在开发调试阶段可以用ulimit命令改变这个限制,允许产生core文件。 首先用ulimit命令改变Shell进程的Resource Limit,允许core文件最大为1024K: $ ulimit -c 1024。

#include<iostream>
using namespace std;
int main()
{
    int a=10;
    a/=0;
    return 0;
}

使用指令修改限制,允许产生core文件;专门制造一个浮点数异常编译并运行后会产生一个和本进程id相关的core文件;我们可以发现这个文件是非常大的,程序运行时如果出现这类异常会将我们的磁盘写满,造成无法进行修改这也是为什么系统默认不允许产生core文件。


信号产生的方式

通过键盘按键产生信号

通过键盘进行信号的产生就像我们上面使用键盘输入crtl +c可以终止一个进程,当这个键盘输入组合键时会产生一个硬件中断,被操作系统获取,解释成为2号信号,发送给目标前台进程。进程会修改自己PCB中的信号位图,表示已经收到信号。

前台进程因为接收到引号,直接对信号进行处理,进而终止进程。

此外常用的组合键含有:ctrl + z 默认暂停进程 ctrl + \ 默认退出进程

通过系统调用/指令产生信号

kill函数

//头文件
#include<sys/types.h>
#include<signal.h>
//函数
int kill(pid_t pid, int sig)

参数说明:

  • pid:表示进程的pid,代表向哪一个进程发送。
  • sig:表示发送信号的编号。 
#include<iostream>
  2 #include<unistd.h>
  3 #include<signal.h>
  4 #include<sys/types.h>                                              
  5 using namespace std;                                                  
 10 int main()                           
 11 {                                    
 12     cout<<"wait 2 signal"<<endl;     
 13     sleep(2);                        
 14     kill(getpid(),9);                
 15     cout<<"WTF"<<endl; 
        return 0;
    }

上面的代码演示了使用kill函数给自身进程产生了9号信号,并由操作系统发送成功;也可以通过另一个进程给一个指定的进程发送指定的信号。

raise函数

//头文件
#include<signal.h>
//函数
int raise(int sig);

参数说明:

  • sig:代表信号编号。
  • raise专门用来给自己发送指定的信号的。 
 #include<iostream>
  2 #include<unistd.h>
  3 #include<signal.h>
  4 #include<sys/types.h>
  5 using namespace std;
 10 int main()
 11 {
 12     cout<<"wait signal"<<endl;
 13     raise(9);    
        reutrn 0;
    }                                                  

硬件异常产生信号

硬件异常被硬件以某种方式被硬件检测到并通知内核,然后内核向当前进程发送适当的信号。例如当前进程执行了除以0的指令,CPU的运算单元会产生异常,内核将这个异常解释 为SIGFPE信号发送给进程。再比如当前进程访问了非法内存地址,,MMU会产生异常,内核将这个异常解释SIGSEGV信号发送给进程。

浮点数异常

#include<iostream>
using namespace std;
int main()
{
    int a=10;
    a/=0;
    return 0;
}

非法地址异常 

#include<iostream>
using namespace std;
int main()
{
    int* a=NULL;
    *a=100;
    return 0;
}

 

由软件条件产生信号

在之前管道的文章,匿名管道如果读端关闭,写端一直写入;操作系统就会发送SIGPIPE(13)号信号终止目标进程。SIGPIPE就是一种由软件条件产生的信号。

alarm函数

//头文件
#include <unistd.h>
//函数
unsigned int alarm(unsigned int seconds);

调用alarm函数可以设定一个闹钟,也就是告诉内核在seconds秒之后给当前进程发SIGALRM信号, 该信号的默认处理动作是终止当前进程。

这个函数的返回值是0或者是以前设定的闹钟时间还余下的秒数。打个比方,某人要小睡一觉,设定闹钟为30分钟之后响,20分钟后被人吵醒了,还想多睡一会儿,于是重新设定闹钟为15分钟之后响,“以前设定的闹钟时间还余下的时间”就是10分钟。如果seconds值为0,表示取消以前设定的闹钟,函数的返回值仍然是以前设定的闹钟时间还余下的秒数。

#include<iostream>
#include<unistd.h>
int cnt = 0;
int main()
{
    alarm(1);
    while(true)
    {
        cnt++;
        cout<<cnt<<endl;
    }
    return 0;
}


今天对Linux下信号的产生的分享到这就结束了,希望大家读完后有很大的收获,也可以在评论区点评文章中的内容和分享自己的看法;个人主页还有很多精彩的内容。您三连的支持就是我前进的动力,感谢大家的支持!!!  

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何选择合适的汽车芯片ERP系统?

随着汽车产业的飞速发展&#xff0c;汽车芯片作为关键组件&#xff0c;其管理变得愈发重要。为了高效管理汽车芯片的生产、销售、库存等各个环节&#xff0c;许多企业开始引入汽车芯片ERP(企业资源规划)系统。那么&#xff0c;如何选择合适的汽车芯片ERP系统呢? 明确需求是关键…

react-JSX基本使用

1.目标 能够知道什么是JSX 能够使用JSX创建React元素 能够在JSX中使用JS表达式 能够使用JSX的条件渲染和列表渲染 能够给JSX添加样式 2.目录 JSX的基本使用 JSX中使用JS表达式 JSX的条件渲染 JSX的列表渲染 JSX的样式处理 3.JSX的基本使用 3.1 createElement()的问题 A. …

小红书3C家电行业种草营销策略打法,纯干货

小红书作为国内种草营销的鼻祖&#xff0c;拥有庞大的年轻用户群体&#xff0c;特别是在3C家电行业&#xff0c;小红书的种草营销效应更是明显。据相关数据显示&#xff0c;小红书3C家电行业的用户关注度持续攀升&#xff0c;尤其是90后和00后&#xff0c;他们对新鲜事物的接受…

C# 学习第四弹——字符串

一、char类型的使用 字符使用单引号&#xff0c;单个字符 转义字符是一种特殊的字符变量&#xff0c;以反斜线开头&#xff0c;后跟一个或多个字符。 输出多级目录可以使用 二、字符串的声明和初始化 1、引用字符串常量 引用字符串常量初始化——字符使用单引号&#xff0…

基于springboot+vue的学科平台系统(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

幻兽帕鲁(Palworld 1.4.11.5.0)私有服务器搭建(docker版)

文章目录 说明客户端安装服务器部署1Panel安装和配置docker服务初始化设置设置开机自启动设置镜像加速 游戏服务端部署游戏服务端参数可视化配置 Palworld连接服务器问题总结 服务端升级&#xff08;1.5.0&#xff09; 说明 服务器硬件要求&#xff1a;Linux系统/Window系统&a…

数据中台:数字中国战略关键技术设施

目录 前言 为何要建设数据中台 数据中台建设痛点 数据中台学习资料 聚焦前沿&#xff0c;方法论体系更新 与时俱进&#xff0c;紧跟时代热点 深入6大行业&#xff0c;提炼实践精华 大咖推荐&#xff0c;数字化转型必备案头书 前言 在数字中国这一国家战略的牵引下&…

谷歌seo推广好还是竞价排名好?

事实上seo跟sem竞价并没有任何冲突&#xff0c;也并没有哪个更好的说法&#xff0c;关键在于理解它们各自的优势与局限性&#xff0c;并根据你的业务&#xff0c;预算来配合 Seo推广的优势在于成本&#xff0c;只要你的网站在搜索结果获得高排名&#xff0c;就能有源源不断的点…

水库安全监测方案(福建地区水库安全监测案例分享)

我司星创易联最近在福建省受到了一个水库安全监测系统项目的委托。该水库位于福建中部山区,作为该地区的重要防洪与供水工程,对下游数十万人的生活产生重大影响。但是因为水库附近地质情况复杂,水库大坝在多次洪水冲击下出现一定病害,亟须全面加强对水库大坝安全状况的监测,以确…

Linux零基础快速入门

Linux的诞生 Linux创始人:林纳斯 托瓦兹 Linux 诞生于1991年&#xff0c;作者上大学期间 因为创始人在上大学期间经常需要浏览新闻和处理邮件&#xff0c;发现现有的操作系统不好用,于是他决心自己写一个保护模式下的操作系统&#xff0c;这就是Linux的原型&#xff0c;当时他…

代码随想录算法训练营第35天 | 435. 无重叠区间 ,763.划分字母区间 , 56. 合并区间

贪心算法章节理论基础&#xff1a; https://programmercarl.com/%E8%B4%AA%E5%BF%83%E7%AE%97%E6%B3%95%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html 435. 无重叠区间 题目链接&#xff1a;https://leetcode.cn/problems/non-overlapping-intervals/ 思路&#xff1a; 相信…

【算法与数据结构】复杂度深度解析(超详解)

文章目录 &#x1f4dd;算法效率&#x1f320; 算法的复杂度&#x1f320; 时间复杂度的概念&#x1f309;大O的渐进表示法。 &#x1f320;常见复杂度&#x1f320;常见时间复杂度计算举例&#x1f309;常数阶O(1)&#x1f309;对数阶 O(logN)&#x1f309;线性阶 O(N)&#x…

SpringMVC 学习(十)之异常处理

目录 1 异常处理介绍 2 通过 SimpleMappingExceptionResolver 实现 3 通过接口 HandlerExceptionResolver 实现 4 通过 ExceptionHandler 注解实现&#xff08;推荐&#xff09; 1 异常处理介绍 在 SpringMVC中&#xff0c;异常处理器&#xff08;Exceptio…

九州金榜|父亲在教育中的作用及重要性

随着社会进步&#xff0c;对比以前教育&#xff0c;现在父亲在教育中的作用越来越明显&#xff0c;孩子的教育离不开父亲&#xff0c;父亲在孩子教育中有什么作用&#xff1f;重要性又是什么呢&#xff1f;下面九州金榜家庭教育就带大家一起分析一下作为父亲&#xff0c;在孩子…

项目解决方案:海外门店视频汇聚方案(全球性的连锁店、国外连锁店视频接入和汇聚方案)

目 录 一、概述 二、建设目标及需求 2.1 建设目标 2.2 需求描述 2.3 需求分析 三、建设方案设计 3.1 系统方案拓扑图 3.2 方案描述 3.3 服务器配置推荐 四、产品功能 4.1 资源管理平台 &#xff08;1&#xff09;用户权限管理 &#xff08;2&#xff09…

pv、pvc

目录 1、什么是pv和pvc 2、pvc的使用逻辑 3、StorageClass 4、pv和pvc相互作用 5、pv的生命周期中&#xff0c;一般有几种状态&#xff1f; 6、一个pv从创建到销毁的流程 7、nfs使用pv和pvc 7.1、配置nfs存储 7.2这里定义5个PV&#xff0c;并且定义挂载的路径以及访问…

Tomcat配置私人共享

tomcat安装在公网IP为x.x.x.x的服务器上 tomcat安装 第一步&#xff0c;下载server-jre-8u202-linux-x64.tar.gz和apache-tomcat-8.5.95.tar.gz安装包。 登录地址&#xff1a;https://www.oracle.com/java/technologies/javase/javase8-archive-downloads.html下载server-jr…

Qt中的QGraphicView和QGraphicScene简单使用

概述&#xff1a;我们利用QGraphicView和QGraphicScene来实现一个简单的视频播放器&#xff0c;然后上面悬浮一些操作的控件&#xff0c;看看怎么来实现。 1、CcTestVideoPlayer类 模拟播放器类&#xff0c;继承QGraphicScene 1.1 CcTestVideoPlayer.h #pragma once#include…

NC65 rest接口 开发 NC65接口开发

一、在对应模块META-INF下编写 xxx.rest 文件,也要放在Home里对应的目录下。 二、开发接口&#xff0c;继承extends AbstractUAPRestResource&#xff0c;&#xff08;有的项目会继承别的方法如&#xff1a;AbstractNCCRestResource&#xff0c;MTFRestResource&#xff1b;有…

ChemDraw Pro 2022:呈现专业化学绘图的极 致之作 mac/win版

PerkinElmer ChemDraw Pro 2022是一款功能强大的化学绘图软件&#xff0c;专为化学家、科研工作者和教育者设计。这款软件凭借其卓越的性能和丰富的功能&#xff0c;已经成为化学绘图领域的领导者。 PerkinElmer ChemDraw Pro 2022软件获取 ChemDraw Pro 2022提供了广泛的化学…