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

news2024/9/21 22:32:41

在这里插入图片描述

文章目录

  • 概述
    • 从生活角度理解信号
    • 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是异常终止

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【 DHT11 温湿度传感器】使用STC89C51读取发送到串口、通过时序图编写C语言

文章目录 DHT11 温湿度传感器概述接线数据传送通讯过程时序图检测模块是否存在 代码实现总结对tmp tmp << 1;的理解对sendByte(datas[0]/10 0x30);的理解 DHT11 温湿度传感器 使用80C51单片机通过读取HDT11温湿度传感的数据&#xff0c;发送到串口。 通过时序图编写相应…

Windows下lapack的编译

文章目录 LAPACK库LAPACK库的地址LAPACK库的安装和编译 LAPACK库 LAPACK&#xff08;Linear Algebra PACKage&#xff09;库&#xff0c;是用Fortran语言编写的线性代数计算库&#xff0c;包含线性方程组求解&#xff08;AXb&#xff09;、矩阵分解、矩阵求逆、求矩阵特征值、…

javac详解 idea maven内部编译原理 自制编译器

起因 不知道大家在开发中&#xff0c;有没有过下面这些疑问。有的话&#xff0c;今天就一次解答清楚。 如何使用javac命令编译一个项目&#xff1f;java或者javac的一些参数到底有什么用&#xff1f;idea或者maven是如何编译java项目的&#xff1f;&#xff08;你可能猜测底层…

4核16G服务器支持多少人?4C16G服务器性能测评

租赁4核16G服务器费用&#xff0c;目前4核16G服务器10M带宽配置70元1个月、210元3个月&#xff0c;那么能如何呢&#xff1f;配置为ECS经济型e实例4核16G、按固定带宽10Mbs、100GB ESSD Entry系统盘。 那么问题来了&#xff0c;4C16G10M带宽的云服务器可以支持多少人同时在线&…

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] LYA的生日派对座位安排(200分) - 三语言AC题解(Python/Java/Cpp)

🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 🍿 最新华为OD机试D卷目录,全、新、准,题目覆盖率达 95% 以上,支持题目在线…

原神运行闪退报错怎么办解决办法 crossover24运行exe游戏程序错误没反应

对于Mac用户来说&#xff0c;能够在Mac上体验Windows游戏是一种极大的便利。然而&#xff0c;当尝试运行热门游戏《原神》时&#xff0c;一些用户可能会遇到闪退或报错的问题。这不仅影响了游戏体验&#xff0c;也让人倍感挫败。幸运的是&#xff0c;有多种方法可以帮助解决这些…

优化德育评估流程:智慧职校的考核类型设置功能

智慧职校德育管理系统的引入标志着教育领域向着更加智能化、高效化方向迈进的重要一步。其中&#xff0c;考核类型设置功能作为系统的核心模块之一&#xff0c;扮演着不可或缺的角色。这一功能的创新之处在于它赋予了学校前所未有的灵活性和自主权&#xff0c;让教育者能够根据…

PyTorch的自动微分模块【含梯度基本数学原理详解】

文章目录 1、简介1.1、基本概念1.2、基本原理1.2.1、自动微分1.2.2、梯度1.2.3、梯度求导1.2.4、梯度下降法1.2.5、张量梯度举例 1.3、Autograd的高级功能 2、梯度基本计算2.1、单标量梯度2.2、单向量梯度的计算2.3、多标量梯度计算2.4、多向量梯度计算 3、控制梯度计算4、累计…

【香橙派开发板测试】:在黑科技Orange Pi AIpro部署YOLOv8深度学习纤维分割检测模型

文章目录 &#x1f680;&#x1f680;&#x1f680;前言一、1️⃣ Orange Pi AIpro开发板相关介绍1.1 &#x1f393; 核心配置1.2 ✨开发板接口详情图1.3 ⭐️开箱展示 二、2️⃣配置开发板详细教程2.1 &#x1f393; 烧录镜像系统2.2 ✨配置网络2.3 ⭐️使用SSH连接主板 三、…

KAFKA搭建教程

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

网络需求实验报告

拓扑图 需求 1、通过DHCP服务&#xff0c;给PC4和PC5分配IP地址、网关、掩码、DNS服务器IP地址 2、Client-1要求手工配置IP地址&#xff0c;为192.168.1.1, c 3、telnet客户端可以远程登录telnet服务器进行设备管理&#xff0c;并成功修改telnet服务器的名字为123 &#xff0c…

Dev—c++小熊猫6.7.5免费下载攻略

点击蓝字 关注我们 今天我来给大家分享一个Dev—c小熊猫6.7.5免费下载攻略&#xff0c;内容如下 1. https://gitee.com/royqh1979/Dev-CPP/releases/tag/v6.7.5 点进这一个官网&#xff0c;一直往下滑&#xff0c;找到第三个选项&#xff0c;把它下载下来。 2. 安装时一些选择…

phpstorm无法实现代码反向追踪 字体变黄(Ctrl+鼠标左键向上一级追踪)问题解决

方法一、.将项目里面的.idea文件删除掉&#xff0c;重新进入phpstorm&#xff0c;这个时候会重新对项目进行编制索引等操作&#xff0c;就会神奇的发现&#xff0c;可以正常追踪了。 当方法一不行时&#xff0c;可以使用方法二 方法二、File->invalidate Caches 去除缓存

Android中Activity生命周期详解

目录 一 典型情况二 异常情况2.1 系统配置改变2.2 系统资源不足kill掉低优先级activity Activity是四大组件之一&#xff0c;也是接触的最多的&#xff0c;一般来说Activity经常是与用户交互的界面。 一 典型情况 先看下google官网&#xff0c;其实已经很清楚了 再来个总结 …

分享一个好用的AI 动漫图片工具 - AI Anime Generator,输入文字,1分钟生成动漫图片_AI绘画工具

使用AI绘画工具&#xff0c;1分钟生成动漫图片-AI Anime Generator 分享一个AI生成动漫图片的网站。输入prompt&#xff0c;即可一键自动生成AI动漫图片。 网站名称&#xff1a;AI Anime Generator 工具地址&#xff1a;https://aianimegenerator.top 网站界面比较简洁&…

AQS和ReentrantLock源码剖析

AbstratQuenedSynchronizer抽象队列同步器 一. 简单理解 源码讲解视频 博客 核心参数 变量state &#xff1a;没加锁state0&#xff0c;加锁state1加锁线程&#xff1a;CAS 设置state1 加锁过程 尝试state的值由0变为1&#xff0c;如果发现state的值已经不为0了而是1&am…

C语言图书馆管理系统

以下是系统部分页面 以下是部分源码&#xff0c;需要源码的私信 #include<stdio.h> #include<stdlib.h> #include <string.h> #include<malloc.h>typedef struct {char student_name[100];char student_number[100];char password[100];int total_bor…

【一刷《剑指Offer》】面试题 46:求 1+2+...+n

力扣对应题目链接&#xff1a;LCR 189. 设计机械累加器 - 力扣&#xff08;LeetCode&#xff09; 牛客对应题目链接&#xff1a;求123...n_牛客题霸_牛客网 (nowcoder.com) 一、《剑指Offer》对应内容 二、分析题目 通常实现递归的时候我们都会利用条件判断语句来决定递归的出…

计算机体系结构||Cache性能分析(4)

实验4 Cache性能分析 4.1实验目的 &#xff08;1&#xff09;加深对Cache基本概念、基本组织结构以及工作原理的理解。 &#xff08;2&#xff09;掌握Cache容量、相关度、块大小对Cache性能的影响 &#xff08;3&#xff09;掌握降低Cache不命中率的各种方法以及它们对提高…

初识网络基础知识

关于网络的一些核心概念 局域网 局域网&#xff08;Local Area Network&#xff0c;简称LAN&#xff09;是一种计算机网络&#xff0c;覆盖的范围通常是相对较小的地理区域&#xff0c;比如一个办公室、一栋大楼或一个校园。 局域网的组成通常包括以下部分&#xff1a; 网络…