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

初谈Linux信号-=-信号的产生

在这里插入图片描述

文章目录

  • 概述
    • 从生活角度理解信号
    • Linux中信号
    • 信号常见的处理方式
    • 理解信号的发送与保存
  • 信号的产生
  • core、term区别

概述

从生活角度理解信号

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

Linux中信号

在Linux操作系统中通过kill -l命令可查看所有的信号:

在这里插入图片描述

信号是从1号开始的的,从信号1到信号31是普通信号,从信号35到信号64称之为实时信号,一般不考虑实时信号。

信号是Linux系统提供的一种向指定进程发送特定事件的一种方式,系统在收到信号时会做识别和处理。

信号产生是异步的:信号的产生和目标进程的运行是两条线,信号可以在程序的任意时刻产生,并且会打断当前正在执行的代码,转而执行信号处理函数。这种异步性质使得信号处理在编程中需要特别注意,因为信号可能会随时打断程序的正常执行流程。

信号常见的处理方式

  1. 默认动作:进程的处理不做任何系统级的设置,新型号都是默认的。默认动作一般都是终止自己,也有暂停或者直接忽略。
  2. 忽略动作:不处理进程或者就是直接忽略
  3. 自定义处理–信号的捕捉

这三种方案只能选择一种,统一称之为信息好处的方式

对信号的捕捉,捕捉一次,后续一直有效:

#include<iostream>
#include<signal.h>
#include<unistd.h>void hander(int sig)
{std::cout<<"get a sig: "<<sig<<std::endl;
}int main()
{signal(2,hander);while(1){std::cout<<"hello gwj,pid: "<<getpid()<<std::endl;sleep(1);}return 0;
}

在这里插入图片描述

理解信号的发送与保存

进程有自己的PCB,是一个结构体,在结构体中有很多的成员变量,信号是给进程发送的,信号在进程中是用位图保存收到的信号的。

变量signals

uint32_t signals;
0000 0000 0000 0000 0000 0000 0000 0000

假设当前需要发送1号信号,只需要将0000 0000 0000 0000 0000 0000 0000 0000变成0000 0000 0000 0000 0000 0000 0000 0001。如此一来,就可以将所有普通信号保存起来。

发送信号:修改指定进程PCB中的信号的指定位图,简单来说其实就是写信号。

PCB是内核数据结构,只有操作系统可以修改内核结构对象中的值。

信号的产生

  1. 通过kill命令,向指定的进程发送指定的信号
  2. 键盘可以产生信号:ctrl+cctrl+\

  1. 系统调用方式
    在这里插入图片描述
#include<iostream>
#include<signal.h>
#include<unistd.h>
#include<sys/types.h>int main(int argc,char *argv[])
{if(argc!=3){std::cerr<<"Usage: "<<argv[0]<<" signum pid"<<std::endl;return 1;}pid_t pid=std::stoi(argv[2]);int signum=std::stoi(argv[1]);kill(pid,signum);return 0;
}

系统调用还有一个产生信号的函数raise
在这里插入图片描述

#include<iostream>
#include<signal.h>
#include<unistd.h>
#include<sys/types.h>void hander(int sig)
{std::cout<<"get a sig: "<<sig<<std::endl;
}int main()
{int cnt=0;signal(3,hander);while(true){sleep(2);raise(3);}
}

上述代码使用raise,是的程序每隔2秒向自己发送一个信号。

使用abort系统调用:
在这里插入图片描述

#include<iostream>
#include<cstdlib>
#include<signal.h>
#include<unistd.h>
#include<sys/types.h>void hander(int sig)
{std::cout<<"get a sig: "<<sig<<std::endl;
}int main()
{int cnt=0;signal(SIGABRT,hander);while(true){sleep(2);abort();}
}

abort自定义捕捉后,但是依然会终止程序。


如果把所有信号都捕捉了,会出现什么现象:
无论哪一个信号都无法终止程序,为了避免这种情况,系统中9号信号不允洗自定义捕捉

真正发送信号的是操作系统,只有操作系统可以发送信号。


  1. 软件条件
    如果一个管道的读端关闭,写端一直在进行,此时写的内容没有意义,操作系统会发送信号SIGPIPE(13号信号),就会直接终止目标进程。
    上面是管道的只是,现在要介绍的是alarm函数:
    在这里插入图片描述
    调用alarm函数可以设定一个闹钟,也就是告诉内核在seconds秒之后给当前进程发SIGALRM信号, 该信号的默认处理动作是终止当前进程。
#include<iostream>
#include<cstdlib>
#include<signal.h>
#include<unistd.h>
#include<sys/types.h>void hander(int sig)
{std::cout<<"sig: "<<sig<<std::endl;exit(1);
}int main()
{int cnt=1;signal(SIGALRM,hander);alarm(1);  //设定1秒后的闹钟 1s后会收到SIGALARMwhile(1){std::cout<<"cnt: "<<cnt<<std::endl;cnt++;}return 0;
}

在这里插入图片描述
注意:
alarm(0)表示取消闹钟,它的返回值表示上一个闹钟的剩余时间。
闹钟设置好后,默认只会触发一次。


  1. 异常产生信号
    硬件异常被硬件以某种方式被硬件检测到并通知内核,然后内核向当前进程发送适当的信号。例如当前进程执行了除以0的指令,CPU的运算单元会产生异常,内核将这个异常解释 为SIGFPE信号发送给进程。再比如当前进程访问了非法内存地址,MMU会产生异常,内核将这个异常解释为SIGSEGV信号发送给进程。
int main()
{while(1){std::cout<<"hello gwj,pid: "<<getpid()<<std::endl;int a=10;a/=0;}
}

在这里插入图片描述

int main()
{while(1){std::cout<<"hello gwj,pid: "<<getpid()<<std::endl;int *p=nullptr;*p=100;}
}

在这里插入图片描述

上述程序直接崩溃,那么程序为什么会崩溃?
程序非法访问导致操作系统给进行发送信号,由于收到信号,程序会退出。野指针对应发送的信号时SIGSEGV,除0对应的信号为SIGFPE

除0错误:在计算机的CPU中,有一个eflag寄存器,这个寄存器中有一个溢出标记位,当100进行除法运算时,在计算机中其实相当于做了多次加法运算,此时溢出标记位标记为1,表示溢出,此时CPU内部报错。操作西永是软硬件资源的管理者,操作系统要随时处理这种操作,操作系统就是向目标进程发送信号。
寄存器只有一套,但是寄存器里面的数据是属于每一个进程的。

野指针错误:当前进程访问了非法内存地址,MMU会产生异常,内核将这个异常解释为SIGSEGV信号发送给进程。

总结: 终止进程实际上是释放进程的上下文数据,包括溢出标志数据或者其他异常数据。

core、term区别

core文件:当一个进程出现了异常,其实进程还在,但是他会帮我们形成一个debug文件,core文件里面存的是进程退出的时候的进程镜像数据,称之为核心转储。

通过ulimit -a我们可以查看当前用户的资源限制情况:

在这里插入图片描述

修改core大小为10240,命令:ulimit -c 10240
在这里插入图片描述

此时我们运行上述除0的程序,程序退出细节不一样,并且形成一个新的文件

为什么云服务器要关闭核心转储:

  • 隐私和安全性考虑: 核心转储文件包含了进程的内存内容,可能会包含敏感信息如密码、密钥等。如果不加以保护或处理,这些信息可能会泄露,对系统安全构成威胁。

  • 减少磁盘空间占用: 核心转储文件通常相对较大,尤其是对于内存占用较大的程序。在生产环境中,如果发生频繁的崩溃或异常终止,这些文件可能会占用大量的磁盘空间,影响系统的正常运行和管理。

  • 性能影响: 生成和写入核心转储文件可能会消耗系统资源和IO操作,对系统的性能产生一定影响。在高性能和高可用性的生产环境中,为了最大化系统的稳定性和响应能力,可能会选择关闭核心转储以减少不必要的系统负载。

Term是异常终止

在这里插入图片描述

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Kafka Producer发送消息流程之消息异步发送和同步发送
  • 【整体介绍】HTML和JS编写多用户VR应用程序的框架
  • node.js的安装及学习(node/nvm/npm的区别)
  • 【闲聊】-Perl的基础语法
  • Python3 学习——基础语法2
  • pyinstall 打包基于PyQt5和PaddleOCR的项目为.exe
  • phpinfo
  • ubuntu24.04 linux bcm94352hmb 无线网卡(带蓝牙功能)无法连接蓝牙设备的解决办法
  • LINUX多进程相关
  • Hadoop3:HDFS存储优化之小文件归档
  • XML 编辑器:功能、选择与使用技巧
  • 北斗高精度服务:无人驾驶领域的创新引擎
  • 基于opencv的图片加水印实现方案
  • ubuntu 通讯学习笔记
  • GESP CCF C++ 三级认证真题 2024年6月
  • 【跃迁之路】【733天】程序员高效学习方法论探索系列(实验阶段490-2019.2.23)...
  • ➹使用webpack配置多页面应用(MPA)
  • AWS实战 - 利用IAM对S3做访问控制
  • css选择器
  • C语言笔记(第一章:C语言编程)
  • IOS评论框不贴底(ios12新bug)
  • JavaScript实现分页效果
  • Linux学习笔记6-使用fdisk进行磁盘管理
  • mac修复ab及siege安装
  • Node项目之评分系统(二)- 数据库设计
  • React16时代,该用什么姿势写 React ?
  • redis学习笔记(三):列表、集合、有序集合
  • Vue学习第二天
  • 阿里云ubuntu14.04 Nginx反向代理Nodejs
  • 警报:线上事故之CountDownLatch的威力
  • 罗辑思维在全链路压测方面的实践和工作笔记
  • 前端技术周刊 2019-01-14:客户端存储
  • 使用阿里云发布分布式网站,开发时候应该注意什么?
  • 腾讯视频格式如何转换成mp4 将下载的qlv文件转换成mp4的方法
  • 微信如何实现自动跳转到用其他浏览器打开指定页面下载APP
  • 一个6年java程序员的工作感悟,写给还在迷茫的你
  • 移动端唤起键盘时取消position:fixed定位
  • 移动互联网+智能运营体系搭建=你家有金矿啊!
  • Semaphore
  • ​secrets --- 生成管理密码的安全随机数​
  • # 消息中间件 RocketMQ 高级功能和源码分析(七)
  • #pragma 指令
  • #进阶:轻量级ORM框架Dapper的使用教程与原理详解
  • $(document).ready(function(){}), $().ready(function(){})和$(function(){})三者区别
  • (26)4.7 字符函数和字符串函数
  • (aiohttp-asyncio-FFmpeg-Docker-SRS)实现异步摄像头转码服务器
  • (arch)linux 转换文件编码格式
  • (C#)if (this == null)?你在逗我,this 怎么可能为 null!用 IL 编译和反编译看穿一切
  • (Demo分享)利用原生JavaScript-随机数-实现做一个烟花案例
  • (八)Docker网络跨主机通讯vxlan和vlan
  • (超简单)构建高可用网络应用:使用Nginx进行负载均衡与健康检查
  • (二十九)STL map容器(映射)与STL pair容器(值对)
  • (附源码)计算机毕业设计SSM疫情社区管理系统
  • (接口封装)
  • (论文阅读23/100)Hierarchical Convolutional Features for Visual Tracking