信号level 1:信号的产生

目录

引言

基础知识(背景)

信号的产生

方法一:通过终端按键产生信号(键盘按键输入)

方式二:通过kill指令

方法3:系统调用

方法四:硬件异常

方法五:软件产生异常

进程结束--信号相关


引言

Linux系统信号的引入,是操作系统对进程进行有效控制和通信的关键组成部分。在多任务操作系统中,进程需要一种方式来响应外部事件或内部条件的变化,而信号提供了一种灵活、高效的解决方案。信号允许一个进程在不中断其正常执行流程的情况下,通知另一个进程或线程某个事件的发生,从而实现进程间的协同和同步。

基础知识(背景)

1. 生活角度的信号

你在网上买了很多件商品,再等待不同商品快递的到来。但即便快递没有到来,你也知道快递来临时, 你该怎么处理快递。也就是你能“识别快递”
当快递员到了你楼下,你也收到快递到来的通知,但是你正在打游戏,需5min之后才能去取快递。那么在在这5min之内,你并没有下去去取快递,但是你是知道有快递到来了。也就是取快递的行为并不是一定要立即执行,可以理解成“在合适的时候去取”。
在收到通知,再到你拿到快递期间,是有一个时间窗口的,在这段时间,你并没有拿到快递,但是你知道有一个快递已经来了。本质上是你“记住了有一个快递要去取”
当你时间合适,顺利拿到快递之后,就要开始处理快递了。而处理快递一般方式有三种:1. 执行默认动作(幸福的打开快递,使用商品)2. 执行自定义动作(快递是零食,你要送给你你的女朋友)3. 忽略快递(快递拿上来之后,扔掉床头,继续开一把游戏)
快递到来的整个过程,对你来讲是异步的,你不能准确断定快递员什么时候给你打电话
2. 技术应用角度的信号
举个栗子:
用户输入命令,在Shell下启动一个前台进程。
用户按下Ctrl-C ,这个键盘输入产生一个 硬件中断,被OS获取,解释成信号,发送给目标前台进程
前台进程因为收到信号,进而引起进程退出。
3. 注意
1. Ctrl-C 产生的信号只能发给前台进程。一个命令后面加个&可以放到后台运行,这样Shell不必等待进程结束就可以接受新的命令,启动新的进程。
2. Shell可以同时运行一个前台进程和任意多个后台进程,只有前台进程才能接到像 Ctrl-C 这种控制键产生的信号。
3. 前台进程在运行过程中用户随时可能按下 Ctrl-C 而产生一个信号,也就是说该进程的用户空间代码执行到任何地方都有可能收到 SIGINT 信号而终止,所以信号相对于进程的控制流程来说是异步
(Asynchronous)的。
4. 信号概念
信号是进程之间事件异步通知的一种方式,属于软中断。
5. kill -l 命令可以察看系统定义的信号列表
每个信号都有一个编号和一个宏定义名称,这些宏定义可以在signal.h中找到,例如其中有定义define SIGINT 2   (2号信号INT就是interrupt:中断的意思)
没有0 32 33号信号。

一共62个信号

1-31:普通信号

34-64:实时信号(收到信号必须立即执行)

编号34以上的是实时信号,本章只讨论编号34以下的信号,不讨论实时信号。这些信号各自在什么条件下产生,默认的处理动作是什么,在signal(7)中都有详细说明: man 7 signal
6. 信号处理常见方式概览
(sigaction函数稍后详细介绍),可选的处理动作有以下三种:
1. 忽略此信号。
2. 执行该信号的默认处理动作。
3. 提供一个信号处理函数,要求内核在处理该信号时切换到用户态执行这个处理函数,这种方式称为捕捉(Catch)一个信号。
其他知识

总结:只允许一个前台,键盘输入是给前台的指令

信号的产生

方法一:通过终端按键产生信号(键盘按键输入)

SIGINT的默认处理动作是终止进程,SIGQUIT的默认处理动作是终止进程并且Core Dump。
首先解释什么是Core Dump。当一个进程要异常终止时,可以选择把进程的用户空间内存数据全部 保存到磁盘上,文件名通常是core,这叫做Core Dump。进程异常终止通常是因为有Bug,比如非法内存访问导致段错误,事后可以用调试器检查core文件以查清错误原因,这叫做Post-mortem Debug(事后调试)。一个进程允许产生多大的core文件取决于进程的Resource Limit(这个信息保存 在PCB中)。默认是不允许产生core文件的,因为core文件中可能包含用户密码等敏感信息,不安全。在开发调试阶段可以用ulimit命令改变这个限制,允许产生core文件。 首先用ulimit命令改变Shell进程的Resource Limit,允许core文件最大为1024K: $ ulimit -c 1024
Ctrl + C :发送2号信号
Ctrl + \ :发送3号信号
在执行程序的时候输入这两个键盘指令,发现程序退出。这是一种软件时间导致的程序终止。
如何证明收到了这两个信号呢?我们可以用信号捕捉函数验证一下
第二个参数是一个函数指针,用来进行信号的自定义处理。
可以看到捕捉到了2号信号,并进行了自定义处理。
也可以捕捉三号信号。
(但是不是所有信号都可以捕捉的)
只要信号捕捉方式设置一次,整个进程都有效!
当然,我们也可以kill -n pid的形式给某个进程发送信号。

方式二:通过kill指令

对进程发送kill指令之后,发现进程收到这个指令并且终止。

方法3:系统调用

kill接口

bash中输入几个字符串,argc就是几

#include <cstdlib>
#include <sys/types.h>
#include <signal.h>
#include <string>
#include <iostream>

using namespace std;

void Usage() 
{
    cout << "Usage:./sig pid signal" << endl;
}

//./sig pid signal
int main(int argc, char* argv[]) 
{
    if (argc != 3) 
    {
        Usage();
        exit(1);
    }
    int pid = stoi(argv[1]);
    int signal = stoi(argv[2]);
    kill(pid, signal);

    return 0;
}

发现可以通过kill调用向进程发送特定的信号。

raise接口

给自己发信号

abort:让自己中止(6号信号)

但是跟直接发6号信号不太一致(kill发送 6 号信号)

三个系统调用/库函数:kill raise abort

方法四:硬件异常

进程退出时的两种方式:1.正常退出:1️⃣正确执行完成2️⃣出现逻辑错误---存在返回状态

                                        2.被信号所杀,异常终止----存在终止信号

当出现野指针与除零错误时,CPU的寄存器会出现异常信息。这个寄存器的信息属于进程的上下文。

对于大多数架构,除以零错误会引发SIGFPE(浮点异常)信号,其信号编号通常是8

当我们执行程序之后,返现另一个执行流(信号)在疯狂打印收到了8号信号,并且没有休眠。

原因:

1.进程是分执行流的,信号引发的执行流是一个独立的执行流。

2.信号一直被触发?

上下文信息随进程的切换而切换

这个OS会管理CPU,知道状态寄存器出异常(CPU在执行进程时转化成硬件问题)

代码出错---状态寄存器出异常--OS检测---向进程发送信号---处理信号

当进程恢复时,会把上下文恢复,从而一直出现浮点异常SIGFPE。

对于野指针,也会引起这样的异常,只不过区分段错误与浮点异常时,存在不同的寄存器去感知这些异常。

所以出现错误时,发送的信号大部分都会导致进程终止,那为什么还打印信息呢?----为了让用户更好的去处理解决错误。

C++的try---catch异常处理一定是信号处理的封装。只不过这个机制太过于简单与落后,大部分公司都有自己独立的异常处理机制。

方法五:软件产生异常

SIGPIPE 是一种由软件条件产生的信号 , 管道 中已经介绍过了。本节主要介绍 alarm 函数和SIGALRM信号。

14号信号:闹钟⏰

alarm函数

参数是闹钟响时的秒数

返回值:提前几秒醒来:参数 - 醒来时间

(

可以设置定时任务

返回值:在设置新的闹钟的时候,可能上次的闹钟可能还有剩余的时间,这个时候返回值就有意义。

#include <iostream>
#include <unistd.h>
#include <signal.h>

using namespace std;

void handler(int sig)
{
    cout << "Received signal " << sig << endl;
}

int main() 
{
    alarm(5);
    signal(SIGALRM, handler);
    while (1)
    {
        sleep(1);
    }
    
    return 0;
}

为什么进程没有一直打印闹钟呢(信号只发了一次))

这是因为闹钟只设置了一次,这并不是硬件层面的异常导致的信号(信号!=异常)

进程结束--信号相关

进程退出时,waitpid的第二个参数status可以获取退出信息,其中低7位表示被信号所杀时的信号信息,次低8位表示的是正常退出时的状态码

对于出异常的进程,大部分都会导致进程终止,但是终止的方式千奇百怪。

这些信号的行为。

Term和core(核心转储相关)是终止

Ign是忽略

Cont是继续

而进程退出当status的倒数第八位就是就是代表着是否存在核心转储。

#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>

using namespace std;

int main()
{
    pid_t id = fork();
    if (id == 0)
    {
        // child
        int cnt = 500;
        while (cnt)
        {
            cout << "i am a child process, pid: " << getpid() << "cnt: " << cnt << endl;
            sleep(1);
            cnt--;
        }

        exit(0);
    }

    // father
    int status = 0;
    pid_t rid = waitpid(id, &status, 0);
    if (rid == id)
    {
        cout << "child quit info, rid: " << rid 
        << " exit code: " << ((status >> 8) & 0xFF) 
        << " exit signal: " << (status & 0x7F) << " core dump: " 
        << ((status >> 7) & 1) << endl; // ? & (0000 0000 ... 0001)
    }
}

为了生产核心转储需要先ulimit -c 10240设置一个非零值。

核心转储文件包含着特定的出错信息。

为什么需要核心转储

运行时错误:什么原因出错,哪行代码出错

-g 用debug发布之后,就可以去gdb调试器调试

核心信息:8号信号        14行出现除零错误

core dump最好关闭:防止打满磁盘

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

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

相关文章

国城杯-misc-Tr4ffIc_w1th_Ste90 [WP]

打开流量包&#xff0c;发现主要是UDP流量&#xff0c;然后还有H264的视频数据 右击&#xff0c;UDP追踪流 然后更换为原始数据 另存为.ts的文件&#xff0c;打开就看到密码 !t15tH3^pAs5W#RD*f0RFL9 打开压缩包是一个文件和一个图片 import numpy as np import cv2 import …

【SpringMVC】参数传递 重定向与转发 REST风格

文章目录 参数传递重定向与转发REST风格 参数传递 ModelAndView&#xff1a;包含视图信息和模型数据信息 public ModelAndView index1(){// 返回页面ModelAndView modelAndView new ModelAndView("视图名");// 或// ModelAndView modelAndView new ModelAndView(…

Minio使用教程

Minio介绍 Minlo是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口&#xff0c;非常适合于存储大容量非结构化的数据&#xff0c;例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等&#xff0c;而一个对象文件可以是任意大小&#xf…

新手前端开发入职公司全流程

作为一名前端开发新手&#xff0c;进入一家公司开启职业生涯是既兴奋又充满挑战的旅程。今天就来和大家分享一下这个过程中的各个环节。 一、入职准备 在收到心仪公司的offer后&#xff0c;可别只顾着高兴啦。首先要准备好入职资料&#xff0c;像身份证、学历证明这些是必不可…

那智机器人报警白屏

那智机器人内存太多白屏报警&#xff01;&#xff01;&#xff01;下面来说说如何消除该报警吧&#xff01;&#xff01;&#xff01; 白屏报警的处理办法 解决办法&#xff1a;&#xff08;外部内存清理&#xff09; 升级操作者权限 &#xff08;当我们在维修见面不能看见我…

rk3568之mpp开发笔记mpp移植到开发板

前言&#xff1a; 大家好&#xff0c;今天给大家介绍的内容是rk平台的mpp编解码这块的内容&#xff0c;在rk目前看到有三套框架涉及到编解码内容&#xff1a; 1、rkmedia 2、rockit 3、mpp 这三种不同形式的编解码方式&#xff0c;后面再做详细的框架对比&#xff0c;今天我…

【设计模式】结构型设计模式总结之代理模式、装饰模式、外观模式、享元模式

文章目录 代理模式示例结构分类动态代理 装饰模式示例结构使用场景与代理模式区别Context 外观模式结构示例使用场景Context 享元模式结构示例使用场景Message 代理模式 代理模式&#xff08;Proxy Pattern&#xff09; 是一种结构型设计模式&#xff0c;它提供了一个代理对象…

CSS一些小点 —— 12.7

1. box-sizing: border-box box-sizing 属性&#xff0c;默认值为 content-box box-sizing: border-box 使padding和border的值不会再影响元素的宽高&#xff1b;padding和border的值算在指定宽高的内部&#xff08;但是外边距依然算做外部&#xff09; 2. overflow: hidden …

【毕业设计选题】深度学习类毕业设计选题参考 开题指导

目录 前言 毕设选题 开题指导建议 更多精选选题 选题帮助 最后 前言 大家好,这里是海浪学长毕设专题! 大四是整个大学期间最忙碌的时光&#xff0c;一边要忙着准备考研、考公、考教资或者实习为毕业后面临的升学就业做准备,一边要为毕业设计耗费大量精力。学长给大家整…

算法基础学习Day4(双指针)

文章目录 1.题目2.题目解答1.查找总价格为目标值的两个商品1.1题目及题目解析1.2算法学习暴力解法优化算法 1.3代码提交 2.三数之和2.1题目及题目解析2.2算法学习2.3代码提交 1.题目 LCR 179. 查找总价格为目标值的两个商品 - 力扣&#xff08;LeetCode&#xff09;15. 三数之…

哪里可以找到高质量的街道夜景短视频素材?夜景素材网站推荐

在短视频创作的浪潮中&#xff0c;街道夜景作为一种视觉效果独特、氛围浓郁的题材&#xff0c;深受创作者的青睐。不论是商业广告、创意短片还是个人Vlog&#xff0c;街道夜景的视频素材都能为你的作品增添不小的分量。那么&#xff0c;在哪里可以找到这些高质量的街道夜景短视…

实习冲刺第四十三天

25.K个一组翻转链表 给你链表的头节点 head &#xff0c;每 k 个节点一组进行翻转&#xff0c;请你返回修改后的链表。 k 是一个正整数&#xff0c;它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍&#xff0c;那么请将最后剩余的节点保持原有顺序。 你不能只是单…

[计算机网络] HTTP/HTTPS

一. HTTP/HTTPS简介 1.1 HTTP HTTP&#xff08;超文本传输协议&#xff0c;Hypertext Transfer Protocol&#xff09;是一种用于从网络传输超文本到本地浏览器的传输协议。它定义了客户端与服务器之间请求和响应的格式。HTTP 工作在 TCP/IP 模型之上&#xff0c;通常使用端口 …

微信创建小程序码 - 数量不受限制

获取小程序码&#xff1a;小程序码为圆图&#xff0c;且不受数量限制。 目录 文档 接口地址 请求方式 功能描述 注意事项 获取 scene 值 请求参数 返回参数 对接 请求方法 获取小程序码 调用获取小程序码 总结 文档 接口地址 https://api.weixin.qq.com/wxa/get…

在做题中学习(79):最小K个数

解法&#xff1a;快速选择算法 说明&#xff1a;堆排序也是经典解决问题的算法&#xff0c;但时间复杂度为&#xff1a;O(NlogK)&#xff0c;K为k个元素 而将要介绍的快速选择算法的时间复杂度为: O(N) 先看我的前两篇文章&#xff0c;分别学习&#xff1a;数组分三块&#…

第427场周赛: 转换数组、用点构造面积最大的矩形 Ⅰ、长度可被 K 整除的子数组的最大元素和、用点构造面积最大的矩形 Ⅱ

Q1、转换数组 1、题目描述 给你一个整数数组 nums&#xff0c;它表示一个循环数组。请你遵循以下规则创建一个大小 相同 的新数组 result &#xff1a; 对于每个下标 i&#xff08;其中 0 < i < nums.length&#xff09;&#xff0c;独立执行以下操作&#xff1a; 如…

【中间件开发】Redis基础命令详解及概念介绍

文章目录 前言一、Redis相关命令详解及原理1.1 string、set、zset、list、hash1.1.1 string1.1.2 list1.1.3 hash1.1.4 set1.1.5 zset 1.2 分布式锁的实现1.3 lua脚本解决ACID原子性1.4 Redis事务的ACID性质分析 二、Redis协议与异步方式2.1 Redis协议解析2.1.1 redis pipeline…

运输层4——TCP格式(重点!)

目录 一、TCP报文段格式 二、最大报文长度 MSS 一、TCP报文段格式 长度&#xff1a;前20个字节固定 后4n个字节&#xff08;报文段格式不固定&#xff09; 1、源端和目的端&#xff1a;各2个字节 作用&#xff1a;指明TCP链接的发送 2、序号 4字节 作用&#xff1…

「Mac玩转仓颉内测版46」小学奥数篇9 - 基础概率计算

本篇将通过 Python 和 Cangjie 双语实现基础概率的计算&#xff0c;帮助学生学习如何解决简单的概率问题&#xff0c;并培养逻辑推理和编程思维。 关键词 小学奥数Python Cangjie概率计算 一、题目描述 假设有一个袋子中有 5 个红球和 3 个蓝球&#xff0c;每次从袋子中随机…

从变更到通知:使用Python和MongoDB Change Streams实现即时事件监听

MongoDB提供了一种强大的功能&#xff0c;称为Change Streams&#xff0c;它允许应用程序监听数据库中的变更事件&#xff0c;并在数据发生变化时立即做出响应。这在mysql数据库是不具备没有这个功能的。又如&#xff1a;我们在支付环节想一直监听支付回调的状态&#xff0c;就…