初谈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后会收到SIGALARM
    while(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是异常终止

在这里插入图片描述

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

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

相关文章

【IntelliJ IDEA】一篇文章集合所有IDEA的所有设置

IntelliJ IDEA 是一款功能强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;其设置涵盖了多个方面&#xff0c;以满足不同开发者的需求和偏好。由于 IDEA 的设置相当复杂和详尽&#xff0c;这里无法在一篇简短的文章中详细介绍所有设置。然而&#xff0c;我可以提供一…

义务外贸wordpress独立站主题

健身器材wordpress网站模板 跑步机、椭圆机、划船机、动感单车、健身车、深蹲架、龙门架、健身器材wordpress网站模板。 https://www.jianzhanpress.com/?p4251 农业机械wordpress网站模板 植保机械、畜牧养殖机械、农机配件、土壤耕整机械、农业机械wordpress网站模板。 …

戴着苹果Vision Pro,如何吃花生米

6月底苹果Vision Pro国内开售&#xff0c;我早早到官网预订了一台。选择必要的配件&#xff0c;输入视力信息&#xff0c;定制符合自己视力的蔡司镜片。确实贵。把主要配件和镜片配齐&#xff0c;要3万6&#xff0c;比Pico、META的眼镜贵一个数量级。 Vision Pro出来后&#x…

复合翼无人机搭载自组网模块集群组网技术实现详解

复合翼无人机作为一种具备高效飞行和长航时特点的飞行器&#xff0c;在多个领域如军事侦察、环境监测、灾害救援等都有着广泛的应用。而为了实现复合翼无人机之间的高效通信&#xff0c;搭载自组网模块实现集群组网技术显得尤为重要。本文将详细介绍复合翼无人机搭载自组网模块…

Java实现随机题库-全站最呆瓜思想,保证你能学会

目录 Blue留言 &#xff1a; 学本篇文章之前所需掌握技能 推荐视频&#xff1a; 代码逻辑思想 步骤&#xff1a; 1、引入依赖 2、做一个excel表格 3、java实现从excel表中取数据 第一步&#xff1a;根据excel上面的字段名&#xff08;如下图&#xff09;&#xff0…

Boost搜索引擎项目相关介绍

Boost搜索引擎相关介绍&#xff1a; 首先&#xff0c;Boost库不具备搜索条件&#xff0c;所以我们这个项目借此实现搜索功能。 项目的核心就是以用户搜索的相关内容在目标数据中进行查找。 首先&#xff0c;我们面临的第一大难题就是目标数据&#xff0c;在这里目标数据就是Boo…

如何学习Spark:糙快猛的大数据之旅

作为一名大数据开发者,我深知学习Spark的重要性。今天,我想和大家分享一下我的Spark学习心得,希望能够帮助到正在学习或准备学习Spark的朋友们。 目录 Spark是什么?学习Spark的"糙快猛"之道1. 不要追求完美,在实践中学习2. 利用大模型作为24小时助教3. 根据自己的节…

51单片机学习(4)

一、串口通信 1.串口通信介绍 写完串口函数时进行模块化编程&#xff0c;模块化编程之后要对其进行注释&#xff0c;以便之后使用模块化函数&#xff0c;对模块化.c文件中的每一个函数进行注释。 注意&#xff1a;一个函数不能既在主函数又在中断函数中 模式1最常用&#xf…

《Towards Black-Box Membership Inference Attack for Diffusion Models》论文笔记

《Towards Black-Box Membership Inference Attack for Diffusion Models》 Abstract 识别艺术品是否用于训练扩散模型的挑战&#xff0c;重点是人工智能生成的艺术品中的成员推断攻击——copyright protection不需要访问内部模型组件的新型黑盒攻击方法展示了在评估 DALL-E …

二、GD32F407VET6使用定时器点灯

零、所需文件及环境&#xff1a; 1、第一章建立好的LED灯闪烁程序 2、编译环境MDK5(KEIL5) 3、一个GD32F407VET6硬件 4、一个下载器j-link 或 st-link等 5.代码编辑器 Notepad &#xff08;可以不要 用记事本也能编译 都是习惯的问题 壹、复制LED灯闪烁程序 1.1 复制le…

25w的理想L6简约民宿,15W的哪吒L拎包入住

文 | AUTO芯球 作者 | 谦行 25w买理想L6 &#xff1f; 踩坑咯&#xff01;你是没看哪吒L吧&#xff01; 哪吒是杂牌&#xff1f;兄弟&#xff01;买车要动脑子&#xff01; 你先去哪吒店里体验一下&#xff01;肠子都给你悔青&#xff01; 上有老下有小&#xff0c;要精打…

MongoDB教程(十七):MongoDB主键类型ObjectId

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; 文章目录 引言一、Object…

Spring AOP(2)原理(代理模式和源码解析)

目录 一、代理模式 二、静态代理 三、动态代理 1、JDK动态代理 &#xff08;1&#xff09;JDK动态代理实现步骤 &#xff08;2&#xff09;定义JDK动态代理类 &#xff08;3&#xff09;代码简单讲解 2、CGLIB动态代理 &#xff08;1&#xff09;CGLIB 动态代理类实现…

Spring系列-04-事件机制,监听器,模块/条件装配

事件机制&监听器 SpringFramework中设计的观察者模式-掌握 SpringFramework 中, 体现观察者模式的特性就是事件驱动和监听器。监听器充当订阅者, 监听特定的事件&#xff1b;事件源充当被观察的主题, 用来发布事件&#xff1b;IOC 容器本身也是事件广播器, 可以理解成观察…

ArcGIS Pro不能编辑ArcGIS10.X的注记的解决办法

​ 点击下方全系列课程学习 点击学习—>ArcGIS全系列实战视频教程——9个单一课程组合系列直播回放 点击学习——>遥感影像综合处理4大遥感软件ArcGISENVIErdaseCognition 一、问题 我们利用ArcGIS Pro编辑ArcGIS10.X系列软件生成的注记要素类的时候&#xff0c;会提示不…

FinClip 率先入驻 AWS Marketplace,加速全球市场布局

近日&#xff0c;凡泰极客旗下的小程序数字管理平台 FinClip 已成功上线亚马逊云科技&#xff08;AWS&#xff09;Marketplace。未来&#xff0c;FinClip 将主要服务于海外市场的开放银行、超级钱包、财富管理、社交电商、智慧城市解决方案等领域。 在全球市场的多样性需求推动…

KAFKA搭建教程

KAFKA搭建教程 期待您的关注 KAFKA学习笔记 帮助更多人 目录 KAFKA搭建教程 1.下载Kafka并解压 2.添加环境变量 3.修改 server.properties 文件 4.将kafka复制到其它节点 5.修改node1、node2节点的broker.id 6.将master的环境变量同步到node1、 node2 7.启动zookeeper…

Elasticsearch:评估搜索相关性 - 第 1 部分

作者&#xff1a;来自 Elastic Thanos Papaoikonomou, Thomas Veasey 这是一系列博客文章中的第一篇&#xff0c;讨论如何在更好地理解 BEIR 基准的背景下考虑评估你自己的搜索系统。我们将介绍具体的技巧和技术&#xff0c;以便在更好地理解 BEIR 的背景下改进你的搜索评估流程…

17_高级进程间通信 UNIX域套接字1

非命名的UNIX域套接字 第1个参数domain&#xff0c;表示协议族&#xff0c;只能为AF_LOCAL或者AF_UNIX&#xff1b; 第2个参数type&#xff0c;表示类型&#xff0c;只能为0。 第3个参数protocol&#xff0c;表示协议&#xff0c;可以是SOCK_STREAM或者SOCK_DGRAM。用SOCK_STR…

视觉巡线小车——STM32+OpenMV(三)

目录 前言 一、OpenMV代码 二、STM32端接收数据 1.配置串口 2.接收数据并解析 总结 前言 通过视觉巡线小车——STM32OpenMV&#xff08;二&#xff09;&#xff0c;已基本实现了减速电机的速度闭环控制。要使小车能够自主巡线&#xff0c;除了能够精准的控制速度之外&#xff0…