LInux-信号1

文章目录

  • 前言
  • 一、信号是什么?
  • 二、学习步骤
    • 使用kill -l命令查看信号列表
        • 可以看到有那么多信号,那么进程是如何识别这么多信号的呢?
    • 使用kill命令终止进程
    • 信号的捕捉
        • kill函数
        • raise函数
        • abort函数
    • Core dump
        • 如何查看自己的核心转储功能是否被打开?
        • 如何打开核心转储功能?
    • 由软件条件产生信号
    • 由硬件异常产生信号


前言

本章主要讲信号的产生与处理以及信号的作用,再延展出core dump的相关概念,信号对于进程十分重要。


一、信号是什么?

信号在我们的日常生活中也应用广泛,如信号灯,当绿灯亮起,我们就知道这条马路我们可以通行。我们今天所学习的信号也是同样的作用,是要让进程接受到不同信号所进行不同的处理方式。

二、学习步骤

使用kill -l命令查看信号列表

在之前学习进程状态的时候,我们就曾使用过kill命令来终止进程,而kill命令就是专门用来给进程发送信号的,那么常见的信号有哪些?
可以通过在shell输入

kill -l

信号列表

可以看到有那么多信号,那么进程是如何识别这么多信号的呢?

在每一个进程的PCB中都存储相对应的信号位图结构,那么我们就可以大概知道,这种位图结构只需要由0置1就可以实现对信号的接受,而实际上也就是如此。

我们再来看上面这幅图,左边是它们的信号编号,右边则是它们的宏名称。
在这里插入图片描述

我们今天所讨论的是1-31的信号,其中34以上的信号为实时信号,不在我们本章的学习范畴中。

使用kill命令终止进程

我们可以先写一个死循环程序,使用kill终止进程
在这里插入图片描述
在这里插入图片描述
右侧在跑死循环程序,左侧使用ps axj命令查看运行进程的pid,再使用kill -2 pid命令来终止该进程。

所以这里我们就是对目标进程使用2号信号来终止该进程。

信号的捕捉

进程对于信号有三种处理方式:
1.默认处理
2.忽略(忽略也是一种处理方式,一般是等到合适的时间再进行信号处理)
3.自定义(捕捉信号)

对于信号的捕捉,系统给了我们这样一个接口函数,使用man 2 signal查看signal函数
在这里插入图片描述
这里的sighandler_t是函数指针。

signal函数的主要作用就是用于自定义捕捉信号,将signum的信号处理方式变换成handler的处理方式

代码如下(示例):

#include<iostream>
#include<cstdlib>
#include<unistd.h>
#include<signal.h>void catchSign(int signum)
{std::cout << "捕捉到" << signum << "号信号 pid:" << getpid() << std::endl;
}
int main()
{signal(SIGINT,catchSign);//signal(2,catchSign);while(true){std::cout << "hello " << getpid() << std::endl; sleep(1);}return 0;
}

运行这一串代码之后,我们再尝试使用kill -2 pid 命令,就会发现
在这里插入图片描述
进程收到2号信号后不是终止进程,而是打印出我们catchSign的内容
然后如果你这个时候先想用ctrl+C来终止进程,你会发现也无法终止进程
在这里插入图片描述
这是为什么? 因为ctrl+C这一组合键就是被OS识别为向前台进程发送2号信号!
我们还可以使用ctrl+\来终止进程。而ctrl+\其实也是被OS识别为向前台进程发送3号信号。

kill函数

在这里插入图片描述
shell命令有kill命令,C语言也提供了一个kill函数,可以向pid进程发送sig号命令。

raise函数

在这里插入图片描述
这个函数也是C语言提供的函数,用于对自己这个进程发送sig信号。

abort函数

在这里插入图片描述abort函数使当前进程接收到(6)SIGABRT信号而异常终止。

Core dump

通过在shell输入 man 7 signal我们可以看到
在这里插入图片描述
Term代表终止,那么Core呢? 我们刚刚也尝试使用了3号信号,进程仍然也终止了。这里的Core其实是指 触发该信号可能会发生Core dump(核心转储).

曾经我们在学习进程退出的时候,我们对于进程的退出状态有过探讨,如果进程由于收到信号异常退出,第8个bit位为core dump标志。 所以,核心转储到底是什么? 它其实是为了保护进程在运行过程中所产生的数据,将内存的数据转储到磁盘中, 这就是核心转储!

示例代码:

#include<iostream>
#include<cstdlib>
#include<unistd.h>
#include<signal.h>
#include<wait.h>
int main()
{pid_t id = fork();if(id == 0){sleep(1);std::cout<<"子进程 " << getpid() << ":即将异常退出" << std::endl;raise(SIGQUIT);}int status = 0;waitpid(id, &status, 0);std::cout << "父进程: " << getpid() << " 子进程: " << id << " exit sign: " <<\(status & 0x7F) << " is core: " << ((status >> 7) & 1 ) << std::endl;return 0;
}

这段代码主要是让子进程向自己发送3号信号,并且3号信号是Core,父进程用status接收子进程的退出状态,通过按位与和右移bit位的方式,我们分别可以得到子进程退出时收到的信号和Core dump位。

运行如下
在这里插入图片描述

奇怪了,为什么这里的core还是0呢? 实际上是因为我这里使用的是远端云服务器,而在云服务器上,核心转储功能是被默认关闭的!如果你使用的是虚拟机,虚拟机是默认打开的!

如何查看自己的核心转储功能是否被打开?

在shell输入ulimit -a命令
在这里插入图片描述

如何打开核心转储功能?

在shell输入ulimit -c size

需要注意的是core file的单位是block,因为要存储进程中所产生的数据还是要一定的磁盘空间来存储的,所以size不能太小。
在这里插入图片描述
注意:如果这里修改core file size 失败,尝试使用sudo来添加root权限。

这次我们打开了核心转储功能,再来试试上面的代码运行结果是否不同。
在这里插入图片描述
这次我们的core dump位成功为1,并且我们当前路径下还多出了一个core文件,该文件为二进制文件。

由软件条件产生信号

顾名思义,就是达到软件某种条件则会产生的信号,我们以alarm和SIGALRM信号为例。

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

像alarm给进程设一个闹钟,当闹钟时间到了,达到了设定条件就发送信号,就叫做由软件条件产生信号。

通过alarm我们可以来测一测我们cpu每秒运算能力。

#include<iostream>
#include<cstdlib>
#include<unistd.h>
#include<signal.h>
#include<wait.h>long long count = 0;void catchALRM(int signum)
{std::cout << "count: " << count << std::endl;alarm(1);
}int main()
{signal(SIGALRM,catchALRM);alarm(1);while(1){++count;}return 0;
}

在这里插入图片描述
这就是我的云服务器的cpu运算能力。

由硬件异常产生信号

对于我们而言最常见的就是除0的浮点数异常和野指针所产生的越界访问的异常。
这种其实是硬件上所发现的异常,然后再对进程发送终止信号。

先说SIGFPE浮点数异常信号,大家应该都知道我们程序内部进行的运算都是由cpu进行的,当出现除0时,cpu的状态寄存器会记录浮点数错误,然后OS在计算完毕后进行检查就会发送对进程发送SIGFPE信号。

野指针也是一样的,我们的进程中的虚拟内存的数据要映射到物理内存,会经过MMU(Memory Manager Unit内存管理单元)发现越界访问,也就发送对应的SIGSEGV信号,Segmentation violation段错误。


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

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

相关文章

公司如何防止终端核心文件数据\资料外泄、泄漏?

如何防止电脑文件被拷贝&#xff1f; 防止电子文件泄密是一个重要的信息安全问题。 PC端地址&#xff1a; https://isite.baidu.com/site/wjz012xr/2eae091d-1b97-4276-90bc-6757c5dfedee 以下是一些建议的措施&#xff1a; 加强员工教育和培训&#xff1a;提高员工对电子文…

【Python】2019年蓝桥杯省赛真题——完全二叉树的权值

蓝桥杯 2019 省 A&B&#xff1a;完全二叉树的权值 题目描述 给定一棵包含 N N N 个节点的完全二叉树&#xff0c;树上每个节点都有一个权值&#xff0c;按从上到下、从左到右的顺序依次是 A 1 , A 2 , ⋯ A N A_1,A_2, \cdots A_N A1​,A2​,⋯AN​&#xff0c;如下图所…

FISCO BCOS(十七)利用脚本进行区块链系统监控

要利用脚本进行区块链系统监控&#xff0c;你可以使用各种编程语言编写脚本&#xff0c;如Python、Shell等 利用脚本进行区块链系统监控可以提高系统的稳定性、可靠性&#xff0c;并帮助及时发现和解决潜在问题&#xff0c;从而确保区块链网络的正常运行。本文可以利用脚本来解…

【网站项目】167校园失物招领小程序

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

四、分类算法 - 随机森林

目录 1、集成学习方法 2、随机森林 3、随机森林原理 4、API 5、总结 sklearn转换器和估算器KNN算法模型选择和调优朴素贝叶斯算法决策树随机森林 1、集成学习方法 2、随机森林 3、随机森林原理 4、API 5、总结

无人机快递(物流)技术方案,无人机快递(物流)基础知识

无人机快递技术是一种利用无人机进行快递配送的先进技术。通过利用无人机&#xff0c;快递企业能够在偏远地区或难以通行的地区提供配送服务&#xff0c;同时提高配送效率并降低人力成本。 无人机基本情况 无人驾驶飞机简称“无人机”&#xff0c;是利用无线电遥控设备和自备的…

板块一 Servlet编程:第七节 ServletContext对象全解与Servlet三大域对象总结 来自【汤米尼克的JAVAEE全套教程专栏】

板块一 Servlet编程&#xff1a;第七节 ServletContext对象全解与Servlet三大域对象总结 一、什么是ServletContext对象二、获取ServletContext对象及常用方法&#xff08;1&#xff09;获取 ServletContext 对象&#xff08;2&#xff09;ServletContext对象提供的方法 三、se…

js设计模式:依赖注入模式

作用: 在对象外部完成两个对象的注入绑定等操作 这样可以将代码解耦,方便维护和扩展 vue中使用use注册其他插件就是在外部创建依赖关系的 示例: class App{constructor(appName,appFun){this.appName appNamethis.appFun appFun}}class Phone{constructor(app) {this.nam…

开年红!亚信安全荣获2023年网络安全国家标准优秀实践案例一等奖

近日&#xff0c;全国网络安全标准化技术委员会&#xff08;以下简称“网安标委”&#xff09;正式发布《关于公布2023年网络安全国家标准优秀实践案例获奖名单的通知》&#xff0c;由国家信息中心牵头&#xff0c;亚信安全等多家单位联合申报的“GB/T42583-2023《信息安全技术…

利用RBI(Remote Browser Isolation)技术访问ChatGPT

系统组网图 #mermaid-svg-Bza2puvd8MudMbqR {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-Bza2puvd8MudMbqR .error-icon{fill:#552222;}#mermaid-svg-Bza2puvd8MudMbqR .error-text{fill:#552222;stroke:#552222;…

惠尔顿安全审计系统任意文件读取漏洞

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…

SpringMVC(十二)SpringMVC执行流程

一、SpringMVC常用组件 DispatcherServlet:前端控制器,不需要工程师开发,由框架提供 作用:统一处理请求和响应,整个流程控制的中心,由它调用其它组件处理用户的请求 HandlerMapping:处理器映射器,不需要工程师开发,由框架提供 作用:根据请求的url、method等信息查找Han…

嵌入式学习之Linux入门篇——使用VMware创建Unbuntu虚拟机

目录 主机硬件要求 VMware 安装 安装Unbuntu 18.04.6 LTS 新建虚拟机 进入Unbuntu安装环节 主机硬件要求 内存最少16G 硬盘最好分出一个单独的盘&#xff0c;而且最少预留200G&#xff0c;可以使用移动固态操作系统win7/10/11 VMware 安装 版本&#xff1a;VMware Works…

Linux网络----防火墙

一、安全技术和防火墙 1、安全技术 入侵检测系统&#xff08;Intrusion Detection Systems&#xff09;&#xff1a;特点是不阻断任何网络访问&#xff0c;量化、定位来自内外网络的威胁情况&#xff0c;主要以提供报警和事后监督为主&#xff0c;提供有针对性的指导措施和安…

Leetcode3034. 匹配模式数组的子数组数目 I

Every day a Leetcode 题目来源&#xff1a;3034. 匹配模式数组的子数组数目 I 解法1&#xff1a;暴力遍历 设数组 nums 的长度为 m&#xff0c;数组 pattern 的长度为 n。 遍历数组 nums 的每个长度是 n1 的子数组并计算子数组的模式&#xff0c;然后与数组 pattern 比较…

PyCharm 新建目录 (directory or folder)

PyCharm 新建目录 [directory or folder] 1. 新建目录2. Enter new directory name -> OKReferences 1. 新建目录 right mouse click on the project -> New -> Directory 2. Enter new directory name -> OK ​​​ References [1] Yongqiang Cheng, https:/…

Redis-内存管理

Redis是基于内存存储的&#xff0c;非关系型&#xff0c;键值对数据库。因此&#xff0c;对Redis来说&#xff0c;内存空间的管理至关重要。那Redis是如何内存管理的呢&#xff1f; 一、最大内存限制 Redis 提供了 maxmemory 参数允许用户设置 Redis 可以使用的最大内存大小。…

YOLOv8改进 | 进阶实战篇 | 利用辅助超推理算法SAHI推理让小目标无所谓遁形(支持视频和图片)

欢迎大家订阅我的专栏一起学习YOLO! 一、本文介绍 本文给大家带来的是进阶实战篇,利用辅助超推理算法SAHI进行推理,同时官方提供的版本中支持视频,我将其进行改造后不仅支持视频同时支持图片的推理方式,SAHI主要的推理场景是针对于小目标检测(检测物体较大的不适用,…

DockerFile的应用

DockerFile的应用 一、介绍1 构建的三步骤2 构建的过程 二、常用命令三、DockerFile案例1 创建DockerFile文件2 使用DockerFile文件构建镜像3 启动容器并验证 四 DockerFile添加数据卷 一、介绍 DockerFile是用来构建Docker镜像的构建文件&#xff0c;是由一系列命令和参数构成…

鸿蒙会成为安卓的终结者吗?

随着近期鸿蒙OS系统推送测试版的时间确定&#xff0c;关于鸿蒙系统的讨论再次升温。 作为华为自主研发的操作系统&#xff0c;鸿蒙给人的第一印象是具有颠覆性。 早在几年前&#xff0c;业内就开始流传鸿蒙可能会代替Android的传言。毕竟&#xff0c;Android作为开源系统&…