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

Linux——信号概念与信号产生方式

目录

一、概念

二、前台进程与后台进程

1.ctrl+c

2.ctrl+z

三、信号的产生方式 

1.键盘输入产生信号

2.系统调用发送信号

2.1 kill()函数

2.2 raise()函数

2.3 abort()函数

3.异常导致信号产生

3.1 除0异常

3.2 段错误异常 

4.软件条件产生信号

4.1 管道

4.2 闹钟

四、核心转储

总结


一、概念

生活中,我们也经常遇到信号,比如早八的闹钟、红绿灯、鲁大师在电脑里面抽烟、周杰伦的到底有谁知道~是几点的方向~你~才~会~收~到~暗~号~。在信号还没有产生的时候,我们已经知道什么样的信号需要如何去处理,比如早八的闹钟,在闹钟响之前,我们就知道早上要么起床去上课,要么把闹钟一关继续睡觉。

信号产生了,我们不一定要立即处理他,而是在合适的时候处理。比如你肚子疼,需要拉肚子,但是游戏已经开了,对抗路已经在操作了,今天不管,你有本事就拉裤兜,必须先把这把打完再去。因此我们要对信号进行暂时保存

同时,我们并不清楚具体什么时候肚子痛,因此信号到来相对于我现在正在打的游戏,是异步(多执行流同时进行操作)的。

小总结:

我们能识别信号,同时知道该如何处理

信号是异步的

可以对信号进行暂时保存

在合适的时候处理信号

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

二、前台进程与后台进程

1.ctrl+c

进程在运行时,一般都是前台进程,如下代码,./mytest运行起来,我们输入命令没用反应,但我们运行时输入ctrl+c可以终止掉进程。

如果我们执行的时候在后面加上 & ,就让进程在后台运行,此时输入命令可以反应,但是进程不能被ctrl+c终止。 

这是因为前台进程只能有一个,后台进程可以有多个,由于shell也是一个进程,因此当进程在前台运行时,shell需要退入到后台进程中去,因此无法接受指令。而你现在输入ctrl+c终止进程,就是让前台进程终止,自然进程就结束了。

而当你进程以后台方式启动时,前台进程是shell,因此输入指令可以有结果,如果你输入ctrl+c,shell自己会保护自己,无法被ctrl+c终止,后台进程并没有收到ctrl+c,因此无法终止后台进程。

之前我们提到,后台进程可以有多个,比如现在我们重定向到log1.txt与log2.txt,输入指令jobs可以看到后台进程的运行情况。

他们在后台运行,并不影响前台shell接受指令,同时ctrl+c也无法终止。

我们输入fg + number,就可以将后台进程提到前台来,输入ctrl+c就可以终止掉该进程了。

小总结:判断是前台进程还是后台进程,看shell有没有能力接受用户输入,有就是后台进程,没有就是前台进程。 

2.ctrl+z

输入ctrl+z可以暂停前台进程,但是被暂停的进程会自动放到后台,也就是我输入指令命令行能接受了。

现在我们输入 bg+number ,就可以将暂停的后台进程继续运行。

小总结:

  • ./mytest & 让进程在后台运行
  • jobs 查看后台进程
  • fg + number 将后台进程放到前台
  • ctrl+z 暂停前台进程并放到后台
  • bg + number 将暂停的后台进程继续执行    

三、信号的产生方式 

1.键盘输入产生信号

在上面,我们学习ctrl+c终止前台进程,其实ctrl+c的本质上就是信号,他是信号表中的2号信号。

我们可以通过写代码的方式来查看该现象。

signal函数:能将收到的信号做自定义处理

  • 参数1:信号num
  • 参数2:返回值为void,参数为int的函数指针

#include<iostream>
#include<unistd.h>
#include<signal.h>using namespace std;void sighandler(int signo)
{cout<<"收到了"<<signo<<"号信号"<<endl;exit(1);
}int main()
{signal(2,sighandler);while(1){cout<<"pid: "<<getpid()<<endl;sleep(1);}
}

运行后发现,输入ctrl+c,会打印出内容,同时发送2号指令也会打印出相同的内容,由此可见,ctrl+c 等价于发送2号信号 。也就是键盘输入可以产生信号。

  • 我们知其然,还要知其所以然。
  • 我们在键盘中输入ctrl+c,会被操作系统接受到你的输入,因为操作系统是进程的管理者,他判断出你输入的内容是终止信号,同时是输入给当前运行的前台进程的。那么操作系统肯定需要告诉进程,信号到来了,你赶紧处理。
  • 在进程的角度来看,进程一定要通过存储来表示自己是否收到信号,收到了哪种信号。这完全可以通过位图来实现,比特位的位置代表收到的哪种信号,比特为的内容0/1代表是否收到信号。由于普通信号只有1-31个,因此用32位的整形变量就可以判断了。

  • 我们之前提到,在信号没有到来时,进程就已经知道该如何处理相关信号,因此进程还得有一张自己的函数指针数组,数组的下标与信号的编号相关,于是,当发现信号位图中有信号的到来,知道是哪一张信号,然后会调用信号相关的函数进行执行。

  • 操作系统向目标进程发送信号,其实本质上是写信号,将该进程信号位图的相关位置设置为1​

那么既然ctrl+c是一个信号,之前我们学过的ctrl+z,也应该是信号咯。当然没错,ctrl+z是20号信号SIGTSTP。还有ctrl+\,是3号信号

跟之前一样,使用signal捕获一下2号信号,3号信号,和20号信号。

9号信号不可被自定义捕捉,因为操作系统得有能力杀死任意进程,如果某个进程是恶意进程,一直在读取你的数据,或者对操作系统做破坏,那么该进程捕捉了所有信号,岂不是杀不掉了,因此操作系统设置9号信号不可被捕捉。

2.系统调用发送信号

2.1 kill()函数

有一个kill的系统调用函数,他可以往指定的进程发送指定信号。我们可以通过该函数来发送信号。

kill:给指定进程发送信号

  • 参数1:进程pid
  • 参数2:信号编号

代码如下 

#include<iostream>
#include<unistd.h>
#include<signal.h>
#include<string>using namespace std;void Usage(const string& proc)
{cout<<"\n Usage: "<< proc <<" -signumber process"<<endl;
}int main(int argc,char* argv[])
{if(argc!=3){Usage(argv[0]);exit(0);}int signumber = stoi(argv[1]+1);int processpid = stoi(argv[2]);kill(processpid,signumber);
}

 我们就可以利用kill函数,给他传信号与进程pid,即可将信号发送给此进程。

2.2 raise()函数

kill是给任意进程发送任意信号,而raise是给自己发送任意信号

kill:给指定进程发送信号

  • 参数1:信号编号

使用很简单,如下,raise(2)代表给自己发送2号信号 

 因为我们自定义捕捉了,因此会一直收到2号信号。

2.3 abort()函数

 给自己发送abort信号,是6号信号,参数返回值都不管,直接调用即可。

我们发现,进程确实收到了6号信号,我们sighandler里面并没有让进程退出,但是进程却被Aborted终止,这是abort函数的特点,就是进程收到6号信号,你可以自定义捕捉,但捕捉完毕我仍然会终止

3.异常导致信号产生

C++我们学过异常,发生异常了,代码并不会再往后面执行,而是直接终止,除非你捕获了异常。

3.1 除0异常

如下代码,你发生了除0错误,编译的时候就会警告,当你执行的时候,告诉你浮点数异常。这是8号信号 SIGFPE。

我们将信号捕捉,运行,我们并没有写循环,按道理只会打印一次,这里发现进程在一直打印消息。

这是因为进程在运行的时候,会将进程中的数据放到CPU里面的寄存器去运行,现在CPU运算发现了除0错误,会给相应的标志位写上1,记录你的错误,操作系统就知道进程的错误了(因为操作系统是软硬件资源的管理者),那么操作系统需要发送对应信号干掉目标进程。

但是你自己的操作,将信号自定义捕捉了,杀死不了,而后进程就切换了,当进程又切换回来时,操作系统又发现你对应的标志位为1,因此又给你发送信号,从此往复,会一直发送信号,却又杀不掉你。

3.2 段错误异常 

我们写C/C++代码的时候,经常会遇到段错误。比如野指针,越阶访问等等。段错误异常是11号信号SIGSEGV,因此我们捕捉11号信号看看结果。

跟之前一样,没有写循环,依然一直报错。这是在访问虚拟内存页表时,发现页表中没有对应内容虚拟到物理的映射。发生段错误,标志位设置,操作系统发送信号给进程,进程收到信号并自定义捕捉,进程切换,又回到该进程,发现标志位为1,继续发送信号,继续套娃。

4.软件条件产生信号

4.1 管道

我们之前在学习管道的时候,当我们把读端关闭的时候,写端会直接终止,因为操作系统给写端发送SIGPIPE信号,告诉写端,兄弟别舔了,她已经把你拉黑了。此时我们并没有涉及到寄存器或者其他硬件设备,虽说有内存,但是内存空间都是我自己开辟的呀,我自己的东西我爱咋用咋用,操作系统不会无缘无故给你发信号,这就叫软件条件。

4.2 闹钟

alarm:可以设置闹钟->给当前进程发送14号信号

参数:设置几秒中后的闹钟

返回值:正常返回0,闹钟提前返回剩余时间。

在5次打印后收到了消息,返回值为0。 

综上,产生信号的方式有很多,但是发送信号只能由操作系统来完成!!!也就是向进程PCB中的信号位图写入。

四、核心转储

首先解释什么是Core Dump。当一个进程要异常终止时,可以选择把进程的用户空间内存数据全部保存到磁 盘上,文件名通常是core,这叫做Core Dump。

命令行输入指令 man 7 signal ,往下翻可以查看信号的详细信息,这里可以看到信号的动作有Term、Core、Ign(ignore)、Cont(continue)、Stop。

其他的都比较好理解,比如Ign忽略,Cont继续,Stop暂停。但是还有Term和Core这两种,我们学过的信号这两种类型都有,他们都是终止进程,有什么区别呢?

我们发现Core中有SIGABRT、SIGFPE、SIGSEGV等等,他们都比较像异常情况。报错的具体代码尚不清楚。需要用户进一步排查

Term中的SIGINT(键盘中断)、SIGKILL(杀死进程)等等,其实他们都没犯错, 只是被杀掉了。结果很清楚

你的代码如果出现了Core类型的错误,其实会发生core dump(核心转储),也就是在当前目录下多出一个以进程pid命名的 core.pid 文件。我们可以通过查看gbd查看代码具体报错位置信息。但是core dump功能是被默认关闭的。

输入指令ulimit -a可以查看系统的配置项,其中第一项core file size就是core dump,大小为0,我们可以将他大小设置一下

输入指令ulimit -c + size,就可以更改core file size 的大小,这是内存级别的,也就是重启xshell会自动恢复。 

 现在再更改代码并运行就会发现多了core dumped,发生了核心转储。

我们现在gdb调试mytest,同时在gdb中输入core-file + core.pid ,此时就可以看到该文件是在具体哪个地方出错。 

 

总结

  • 信号的产生,最终都要由操作系统来进行执行,这是因为操作系统是进程的管理者。
  • 进程在信号到来不会立即处理,而是在合适的时候处理。
  • 由于信号不会被立即处理,因此信号需要暂时被进程记录下来,记录在信号位图中。
  • 信号在没有收到信号的时候,已经知道自己该如何处理信号。
  • 操作系统向进程发送信号,本质是向目标进程的信号位图中写信号(置1)。

下一章:信号的保存与处理 

相关文章:

Linux——信号概念与信号产生方式

目录 一、概念 二、前台进程与后台进程 1.ctrlc 2.ctrlz 三、信号的产生方式 1.键盘输入产生信号 2.系统调用发送信号 2.1 kill()函数 2.2 raise()函数 2.3 abort()函数 3.异常导致信号产生 3.1 除0异常 3.2 段错误异常 4.软件条件产生信号 4.1 管道 4.2 闹钟…...

赋值语句还能当判断条件?涨芝士了!

赋值和条件看似是C语言中毫不相关的两个概念&#xff0c;虽然实际过程中我猜测不会有太多这种不太符合常理的情况出现&#xff0c;但是现在在学习的过程中&#xff0c;为了出题而出题总是会整出一些花活出来.....这很难不让人联想起高中时一些大佬为了彰显自己的数学天赋而自己…...

数据结构 - 算法效率|时间复杂度|空间复杂度

目录 1.算法效率 2.时间复杂度 2.1定义 2.2大O渐近表示法 2.3常见时间复杂度计算举例 3.空间复杂度 3.1定义 3.2常见空间复杂度计算举例 1.算法效率 算法的效率常用算法复杂度来衡量&#xff0c;算法复杂度描述了算法在输入数据规模变化时&#xff0c;其运行时间和空间…...

接口自动化之 + Jenkins + Allure报告生成 + 企微消息通知推送

接口自动化之 Jenkins Allure报告生成 企微消息通知推送 在jenkins上部署好项目&#xff0c;构建成功后&#xff0c;希望可以把生成的报告&#xff0c;以及结果统计发送至企微。 效果图&#xff1a; 实现如下。 1、生成allure报告 a. 首先在Jenkins插件管理中&#x…...

『Apisix安全篇』探索Apache APISIX身份认证插件:从基础到实战

&#x1f680;『Apisix系列文章』探索新一代微服务体系下的API管理新范式与最佳实践 【点击此跳转】 &#x1f4e3;读完这篇文章里你能收获到 &#x1f6e0;️ 了解APISIX身份认证的重要性和基本概念&#xff0c;以及如何在微服务架构中实施API安全。&#x1f511; 学习如何使…...

【01-20】计算机网络基础知识(非常详细)从零基础入门到精通,看完这一篇就够了

【01-20】计算机网络基础知识&#xff08;非常详细&#xff09;从零基础入门到精通&#xff0c;看完这一篇就够了 以下是本文参考的资料 欢迎大家查收原版 本版本仅作个人笔记使用1、OSI 的七层模型分别是&#xff1f;各自的功能是什么&#xff1f;2、说一下一次完整的HTTP请求…...

『大模型笔记』常见的分布式并行策略(分布式训练)

常见的分布式并行策略(分布式训练) 文章目录 一. 为什么分布式训练越来越流行二. 常见的并行策略2.1 数据并行2.2 模型并行2.3 流水并行2.4 混合并行二. 参考文献一. 为什么分布式训练越来越流行 近年来,深度学习被广泛应用到各个领域,包括计算机视觉、语言理解、语音识别、广…...

java 企业工程管理系统软件源码+Spring Cloud + Spring Boot +二次开发+ 可定制化

工程项目管理软件是现代项目管理中不可或缺的工具&#xff0c;它能够帮助项目团队更高效地组织和协调工作。本文将介绍一款功能强大的工程项目管理软件&#xff0c;该软件采用先进的Vue、Uniapp、Layui等技术框架&#xff0c;涵盖了项目策划决策、规划设计、施工建设到竣工交付…...

3D数据格式导出工具HOOPS Publish如何生成高质量3D PDF?

在当今数字化时代&#xff0c;从建筑设计到制造业&#xff0c;从医学领域到电子游戏开发&#xff0c;3D技术已经成为了不可或缺的一部分。在这个进程中&#xff0c;将3D模型导出为3D PDF格式具有重要的意义。同时&#xff0c;HOOPS Publish作为一个领先的解决方案&#xff0c;为…...

【springboot】闲话 springboot 的几种异步机制 及 长轮询的概念和简单实现

文章目录 引子springboot的几种异步形式开启异步支持和线程池配置&#xff08;重要&#xff09;第一种&#xff1a;Async第二种&#xff1a;Callable<T>第三种&#xff1a;WebAsyncTask<T>第四种&#xff1a;DeferredResult<T> 长轮询的简单实现概念实现服务…...

Mysql---安全值守常用语句

文章目录 目录 文章目录 一.用户权限设置 用户设置 元数据查询 Union联合查询 分组查询 字符串函数 总结 一.用户权限设置 用户设置 #用户创建 create user "用户名""%主机名" identified by "密码" #用户删除 drop user 用户名 #用户查询…...

containerd快速安装指南

1 containerd快速安装指南&#x1f680; 本指南旨在提供一个简洁有效的方法来安装containerd。我们将通过一份易于理解的脚本步骤&#xff0c;指导您完成安装&#x1f527;。请根据您的实际需求&#xff0c;适当调整containerd版本及其相关依赖。 注意事项&#xff1a; 本安装…...

Javascript - 正则表达式相关的一些基础的范例

很久以前的一些学习资料&#xff0c;归档发布&#xff1b; 正则表达式的基础&#xff0c;以HTML代码来示范&#xff1a; <html><head><title></title><script language"javascript">function test(){//从页面要求客户输入一个字符串…...

JUC:线程活跃性(死锁、活锁、饥饿)

文章目录 线程活跃性死锁活锁解饿 线程活跃性 死锁 两个线程相互等待对方已拥有的锁&#xff0c;就会相互一直等待&#xff0c;不会停止。 t1拥有a锁&#xff0c;等待b锁。 t2拥有b锁&#xff0c;等待a锁。 Slf4j(topic "c.Test3") public class st3 {public st…...

RGB到灰度图像的转换原理及例程

RGB到灰度图像的转换是一种常用的图像处理操作&#xff0c;其原理是根据人眼对不同颜色的敏感度&#xff0c;将彩色图像的红、绿、蓝三个通道的像素值按照一定权重进行加权平均&#xff0c;得到灰度图像的像素值。 在RGB图像中&#xff0c;每个像素点由红、绿、蓝三个分量组成…...

PCA+DBO+DBSCN聚类,蜣螂优化算法DBO优化DBSCN聚类,适合学习,也适合发paper!

PCADBODBSCN聚类&#xff0c;蜣螂优化算法DBO优化DBSCN聚类&#xff0c;适合学习&#xff0c;也适合发paper&#xff01; 一、蜣螂优化算法 摘要&#xff1a;受蜣螂滚球、跳舞、觅食、偷窃和繁殖等行为的启发&#xff0c;提出了一种新的基于种群的优化算法(Dung Beetle Optim…...

创建数据库与表单以及管理表单和数据

一、用于创建数据库的命令以及作用 命令作用CREATE DATABASE 数据库名称创建新的数据库DESCRIBE 表单名称描述表单UPDATE 表单名称SET attribute新值WHERE attribute>原始值更新表单中的数据USE 数据库名称指定使用的数据库SHOW databases显示当前已有的数据库SHOW tables显…...

Milvus+ATTU环境搭建

1.使用Docker Compose安装Milvus Standalone 下载安装单机版milvus向量数据库 https://milvus.io/docs/install_standalone-docker.md wget https://github.com/milvus-io/milvus/releases/download/v2.2.12/milvus-standalone-docker-compose.yml -O docker-compose.yml sud…...

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单实战案例 之八 简单水彩画效果

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单实战案例 之八 简单水彩画效果 目录 Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单实战案例 之八 简单水彩画效果 一、简单介绍 二、简单图像浮雕效果实现原理 三、简单水彩画效果案例实现简单步骤 四、注意事项…...

Chrome浏览器 安装Vue插件vue-devtools

前言 vue-devtools 是一个为 Vue.js 开发者设计的 Chrome 插件。它可以让你更轻松地审查和调试 Vue 应用程序。与普通的浏览器控制台工具不同&#xff0c;Vue.js devtools 专为 Vue 的响应性数据和组件结构量身定做。 1. 功能介绍 组件树浏览&#xff1a;这个功能可以让你查…...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”&#xff0c;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

P3 QT项目----记事本(3.8)

3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

spring:实例工厂方法获取bean

spring处理使用静态工厂方法获取bean实例&#xff0c;也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下&#xff1a; 定义实例工厂类&#xff08;Java代码&#xff09;&#xff0c;定义实例工厂&#xff08;xml&#xff09;&#xff0c;定义调用实例工厂&#xff…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

《基于Apache Flink的流处理》笔记

思维导图 1-3 章 4-7章 8-11 章 参考资料 源码&#xff1a; https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

(转)什么是DockerCompose?它有什么作用?

一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用&#xff0c;而无需手动一个个创建和运行容器。 Compose文件是一个文本文件&#xff0c;通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

AspectJ 在 Android 中的完整使用指南

一、环境配置&#xff08;Gradle 7.0 适配&#xff09; 1. 项目级 build.gradle // 注意&#xff1a;沪江插件已停更&#xff0c;推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...