【Linux】初探信号的奥秘

目录

一、引入信号:

1、什么是信号:

二、前后台进程:

三、信号的处理方式:

四、键盘数据与信号:


前言:

在Linux系统编程中,信号(Signal)是一种至关重要的进程间通信机制,它允许操作系统或进程以异步方式通知目标进程某种事件的发生,例如终止进程、处理异常或触发自定义逻辑,无论是开发高并发服务器,还是调试程序中的异常行为,理解信号的原理与应用都是不可或缺的技能

对于信号的学习,我们分成四个步骤

一、引入信号:

1、什么是信号:

在我们的生活中就有许多的信号,比如当我们在网购的时候,当快递到了菜鸟驿站的时候就会给我们发一个信息,这就算是一个信号的产生,如果此时我们正在打游戏,没有时间去处理它,但是会将这个信号记住(哦,我打完这把游戏就要去拿快递)这就是对信号的保存,然后等到我真的去拿快递的时候,这就是对信号的处理

所以一个信号每时每刻都会产生,并且对于信号要做的动作并不需要立即执行,所以就需要有对信号进行保存的机制,等到合适的时候就对这个信号进行处理

在生活中有着很多很多的信号,比如说:古代的狼烟,以前的冲锋号,下课的铃声等等

那我们是怎么认识这些信号的呢?----- 当然是在生活中,被教会的,比如当看到红绿灯就需要停下来等等,当听到下课铃声的时候就知道可以休息了

那么我们回到我们的Linux中,进程也会收到很多信号,当进程收到信号的时候,和我们日常生活一样, 并不需要立刻进行处理,而是等到一个合适的时机在进行处理,那么对于这些信号,进程怎么知道要怎么处理呢?------- 这当然是创建OS的大佬程序员们在创建的时候也创建了一些信号,这样当进程收到对应的信号的时候就会进行对应的动作

所以,对于进程来说:

1、进程必须具备 识别并且能够处理信号的能力 ---- 并且如果信号没有产生也就是进程没有收到信号,也要具备能够处理,识别信号的能力(这也对应着我们的生活中,尽管此时我旁边没有红绿灯,但是我仍然知道当见到红绿灯的时候要怎样做)------ 所以信号的处理能力是属于进程内置功能的一部分

2、当进程收到一个信号的时候,进程可以不立即处理这个信号,等到合适的时候在处理

3、进程在信号产生,到开始被处理的时候,在这段时间窗口就一定会具备保存信号的能力

讲了这么多,我们先来看看在OS中有哪些信号:

如上,可以看到有62种信号,其中没有32 33号信号(具体是有历史原因的,好像是与什么什么冲突了),在信号的学习中,我们只学习前31个信号,这些信号也被叫做普通信号,对于34以后的实时信号我们不展开学习

二、前后台进程:

我们插入地了解下什么是前台进程,什么是后台进程?

在Linux系统中,前台进程后台进程是进程管理的核心概念,两者的运行方式和交互特性存在显著差异

什么是前台进程:

定义:用户通过终端直接启动并与之交互的进程 

当我们在启动进程的时候一般都是启动的前台进程,并且前台进程是能够被ctrl+c热键杀掉的,并且我们发现在输入指令的时候是没有反应的

什么是后台进程:

定义:独立于终端运行,无需用户实时干预的进程

当我们在启动进程的时候再最后加上&符号,这样我们这个进程是后台进程了

如下,我们发现当启动后台进程的时候,我们输入指令的时候居然有反应了,是互不影响的,并且用热键ctrl+c是杀不掉我们的进程的,那么怎么杀死呢?-----用9号信号kill -9 对应的进程pid

对于一个终端,我们是只允许有一个前台进程的,这是因为我们只能有一个进程和用户进行交互,如果有多个进程就会乱了,当我们启动xshell的时候就启动了一个bash这样的前台进程,当我们又运行了一个前台进程的时候,bash进程就变为后台进程了,这也就是为什么启动前台进程的时候,输入指令没有反应,因为我们输入的指令是输入给前台进程的,我们自己执行的前台进程是没有处理这些指令的代码的,所以输入指令也就没有用,当我们输入热键ctrl+c的时候,这本质上是给我们当前进程发送了2号信号来使我们的进程退出的,

那么这个时候就又有问题了,为什么我对bash这个进程进行ctrl+c的时候bash进程没有退出呢?----- 这当然是bash进程内部对这些信号进行特殊处理啦

但是可以有很多个后台进程,这个时候我们输入的指令依然是输给前台进程bash的,这也就是为什么我们启动后台进程之后输入指令依然能够显示对应的动作了,所以ctrl+c也就啥杀不死后台进程,这是因为我输入的指令发送的是前台进程bash,后台进程此时是收不到了----- 那么后台进程就无敌了吗? ----- 这显然也是不可能的,我们此时就需要使用信号,

比如kill -9 待杀死后台进程的pid即可

三、信号的处理方式:

当我们接受一个信号的时候,就会有三种处理方式

比如当我们在等红绿灯的时候:

1、默认状态,红灯停,绿灯行

2、忽略,不管红灯还是绿灯都停或者都行

3、自定义动作,比如当红灯亮的时候就唱歌,当绿灯亮的时候就跳舞

回到我们的进程中,首先学习一个接口:

void(*)(int) 表示一个函数指针,该函数接受一个int参数并返回void,其中sighandler_t就是新类型名,代表上述函数指针类型

如上,这就是对一个信号进行重定义,首先捕捉到对应的信号,再让信号进行我们重定义的动作

对于signal函数,就需要传两个参数
第一个是 要捕捉信号的序号或者对应的宏也可以
第二个参数是 指定信号处理方式,可为自定义函数、系统默认,或忽略

在了解这个函数了,我们就可以来看看ctrl+c这个热键了,这个实际上就是给我们当前进程发送2号信号,我们来验证看看:

#include <iostream>
#include <unistd.h>
#include <signal.h>using namespace std;void myhander(int signo)
{cout<<"process get a signal : "<< signo << endl;// exit(1);
}int main()
{signal(SIGINT,myhander);    while(1){cout<<"i am a process "<< getpid() <<endl;sleep(1);}return 0;
}

其中signal第一个参数其实就是数字定义的宏,可以看看源码:

如上,这是一个进程,我们让他以前台进程的方式运行起来

如上,当运行起来后,我们使用常规的ctrl+c热键是杀不死这个进程的,这是因为ctrl+c热键本质上是向该进程发送2号信号,但是我们在代码中将2号信号的默认行为自定义为在显示器上打印一条消息了,这样ctrl+c就无法给该进程传输2号信号的默认动作了,就只能够通过别的信号,如上图右侧,通过9号信号来杀死该进程了

那么是不是我们将所有信号都重定义了,就无法杀死该进程了呢?

我们编写如下代码来看看结果:

#include <iostream>
#include <unistd.h>
#include <signal.h>using namespace std;void myhander(int signo)
{cout<<"a signal was change : "<< signo << endl;
}int main()
{for(int i = 1;i<=31;i++){signal(i,myhander);}while(1){cout<<"i am a process "<< getpid() <<endl;sleep(1);}return 0;
}

如上,我们将所有信号都进行捕捉,在进行验证

如上,我们先说结论:

9号信号和19号信号是不能够被捕捉的,因为这两个信号是强制用于终止/暂停进程

如果要验证可以像验证上述信号1,2,3一样

signal更深理解:

我们在使用signal函数的时候,一般放在最开始即可,因为signal只需要设置一次,在往后的生命周期中都有效(当捕捉到对应信号后就会重定义为自己新的行为),对于signal第二个参数,这只有在捕捉到信号的时候再回执行上述的函数,如果在以后的生命周期都未捕捉到对应的信号,也就不会调用上述myhander这个函数

四、键盘数据与信号:

键盘的数据是怎么输入给CPU进行处理的?ctrl+c又是怎么变成信号的?

首先,我们在冯诺依曼体系结构中了解到了:键盘是不能够直接将数据给CPU的,必须通过内存,然后在和CPU打交道,所以当键盘里面有数据了,必须是通过OS来和CPU打交道的

那么OS要怎么才能知道键盘中有数据了呢?难道没过一段时间OS都向每一个硬件都问它-----你有没有数据啊?这显然是不可能的,毕竟在我们的计算机中硬件数量很多,并且OS是不会做浪费时间的事情的,那么就需要一个解决方式:

这就需要我们的CPU了,看看上图,CPU与内存之间是不能够直接传输数据的,但是在CPU中有许多针脚,不同的硬件对应着不同的针脚,每一个针脚都有自己的编号,其功能由CPU内部的多个功能模块协同控制

当我们在键盘中按下后,控制信号通过中断单元来告诉CPU:我这键盘有数据了,你快来处理,然后CPU就会获取对应的针脚编号,然后写入寄存器中

在OS中有一个中断向量表这个概念:

中断向量表是一个函数指针,毕竟在Linux下一切皆文件,在这个表中,其成员函数指针就指向访问各种外设的方法

所以,当CPU中的一个对应的寄存器中获取到了对应的针脚编号,就会在OS中的中断向量表中对应的位置找到对应硬件的方法,执行它的读取方法就行了

这样,OS就知道要从键盘中读入数据了,此时,如果读到了ctrl+c之类的组合键,OS就会将这些转化成对应的信号发送给进程;如果读到了普通数据,就会写入对应进程的缓冲区中

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Bugku CTF CRYPTO

Bugku CTF CRYPTO 文章目录 Bugku CTF CRYPTO聪明的小羊ok[-<>]散乱的密文.!? 聪明的小羊 描 述: 一只小羊翻过了2个栅栏 fa{fe13f590lg6d46d0d0} 分 析&#xff1a;栅栏密码&#xff0c;分2栏&#xff0c;一个栏里有11个 ①手动解密 f a { f e 1 3 f 5 9 0 l g 6 d 4 …

数据库的基本操作

目录 一、查看所有的数据库&#xff1a; 二、创建数据库&#xff1a; if not exists : 字符编码集&#xff1a; 排序规则&#xff1a; 三、查看创建的库&#xff1a; 四、修改数据库&#xff1a; 五、删除数据库&#xff1a; if exists&#xff1a; 前言&#xff1a; 在…

IDEA集成DeepSeek,通过离线安装解决无法安装Proxy AI插件问题

文章目录 引言一、安装Proxy AI1.1 在线安装Proxy AI1.2 离线安装Proxy AI 二、Proxy AI中配置DeepSeek2.1 配置本地部署的DeepSeek&#xff08;Ollama方式&#xff09;2.2 通过第三方服务商提供的API进行配置 三、效果测试 引言 许多开发者尝试通过安装Proxy AI等插件将AI能力…

Java+SpringBoot+Vue+数据可视化的音乐推荐与可视化平台(程序+论文+讲解+安装+调试+售后)

感兴趣的可以先收藏起来&#xff0c;还有大家在毕设选题&#xff0c;项目以及论文编写等相关问题都可以给我留言咨询&#xff0c;我会一一回复&#xff0c;希望帮助更多的人。 系统介绍 在互联网技术以日新月异之势迅猛发展的浪潮下&#xff0c;5G 通信技术的普及、云计算能力…

【时时三省】(C语言基础)常量和变量

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 在计算机高级语言中&#xff0c;数据有两种表现形式&#xff1a;常量和变量。 常量 在程序运行过程中&#xff0c;其值不能被改变的量称为常量。数值常量就是数学中的常数。 常用的常量有以…

zabbix故障案例 WEB页面Database error Connection refused

目录 1.思路 2.问题解决 3.其他数据库问题思路 1.思路 当我们遇到 Database error Connection refused的问题的时候一般想到的都是数据库的问题 那我们这时候就顺着这条线索排查 2.问题解决 我们首先先进入数据库 mysql -uzabbix -p123 发现了如下报错 应该是数…

MaxKB+Ollama+DeepSeek1.5B部署知识库

环境信息 练习测试用&#xff0c;所以资源很低&#xff0c;8G显卡。大模型部署在Windows台式机上&#xff0c;MaxKB部署在CentOS虚拟机上。 台式机&#xff1a; 硬件&#xff1a;i7 13900 NV GeForce RTX 3060 Ti 8G显存 32G内存 软件&#xff1a;Windows 11操作系统&…

猿大师播放器:智慧交通Web网页低延迟播放监控RTSP H.265视频解决方案

在智慧城市建设加速推进的今天&#xff0c;智慧交通作为城市"神经系统"正面临前所未有的发展机遇。据统计&#xff0c;2023年全国交通视频监控设备保有量已突破4500万台&#xff0c;日均产生的视频数据量超50PB。但在这些庞大数字背后&#xff0c;行业却普遍面临着&q…

Web3.py 入门笔记

Web3.py 学习笔记 &#x1f4da; 1. Web3.py 简介 &#x1f31f; Web3.py 是一个 Python 库&#xff0c;用于与以太坊区块链进行交互。它就像是连接 Python 程序和以太坊网络的桥梁。 官方文档 1.1 主要功能 查询区块链数据&#xff08;余额、交易等&#xff09;发送交易与…

如何选择工控产线安全软件?

在当今数字化时代&#xff0c;信息安全的重要性不言而喻。随着工业控制系统&#xff08;ICS&#xff09;的广泛应用&#xff0c;主机的安全加固成为了保障企业生产运营稳定的关键环节。MCK-T主机加固系统软件&#xff0c;凭借其卓越的性能和全面的安全防护功能&#xff0c;成为…

系统调用过程

注意&#xff1a;本系统调用过程基于32位操作系统 中断服务程序的寻址过程 1.用户态程序产生系统调用write()&#xff1b; 2.产生中断指令ENTER_KERNEL(int $0x80128)&#xff0c;CPU收到中断指令去查询中断向量表&#xff0c;找出中断号0x80对应的中断服务程序的内存基地址(0…

PHP入门基础学习七(函数3)

九、数组函数 1、合并两个数组 合并两个数组,其中一个当健名,一个当值 注意: array_combine 函数,通过合并两个数组来创建一个新数组,其中的一个数组是键名,另一个数组的值为键值。 2.1、排序函数 对于数组的排序,除了可使用前面讲解的排序算法实现外,PHP还提供了内置…

pycharm管理虚拟环境

不借用Anoconda 1.检查pip所在位置&#xff0c; 因为pip的默认安装路径是python的安装目录下的依赖库路径D:\Program Files\Python397\Lib\site-packages。项目如果用之前pycharm创建的环境是无法加载这个路径的库的。 2.安装时指定安装路径 千万要注意指定安装路径为项目的…

DeepSeek 助力 Vue 开发:打造丝滑的 复选框(Checkbox)

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 Deep…

FMT源码 - module

module 功能模块 1、uMCN uMCN 是 类似于 PX4里面的 uORB 模块。 mcn listmcn echo sensor_imu0mcn echo <topic> [options]options:-n, --number Set topic echo number, e.g, -n 10 will echo 10 times. (朝终端打印的次数)-p, --period Set topic echo peri…

城电科技|会追日的智能花,光伏太阳花开启绿色能源新篇章

当艺术与科技相遇&#xff0c;会碰撞出怎样的火花&#xff1f;城电科技推出的光伏太阳花&#xff0c;以其独特的设计与智能化的功能&#xff0c;给出了答案。这款产品不仅具备太阳能发电的实用功能&#xff0c;更是一件充满科技属性的艺术性光伏产品&#xff0c;吸引了广泛关注…

湖北中医药大学谱度众合(武汉)生命科技有限公司研究生工作站揭牌

2025年2月11日&#xff0c;湖北中医药大学&谱度众合&#xff08;武汉&#xff09;生命科技有限公司研究生工作站揭牌仪式在武汉生物技术研究院一楼101会议室举行&#xff0c;湖北中医药大学研究生院院长刘娅教授、基础医学院院长孔明望教授、基础医学院赵敏教授、基础医学院…

计算机网络————(一)HTTP讲解

基础内容分类 从TCP/IP协议栈为依托&#xff0c;由上至下、从应用层到基础设施介绍协议。 1.应用层&#xff1a; HTTP/1.1 Websocket HTTP/2.0 2.应用层的安全基础设施 LTS/SSL 3.传输层 TCP 4.网络层及数据链路层 IP层和以太网 HTTP协议 网络页面形成基本 流程&#xff1a…

货车一键启动无钥匙进入手机远程启动的正确使用方法

一、移动管家货车无钥匙进入系统的使用方法 基本原理&#xff1a;无钥匙进入系统通常采用RFID无线射频技术和车辆身份识别码识别系统。车钥匙需要随身携带&#xff0c;当车钥匙靠近货车时&#xff0c;它会自动与货车的解码器匹配。开门操作&#xff1a;当靠近货车后&#xff0…

2.2logstash规则配置

工作流程 Logstash工作的三个阶段&#xff1a; input数据输入端&#xff0c;以接收来自任何地方的源数据 * file&#xff1a;从文件中读取 * syslog&#xff1a;监听在514端口的系统日志信息, 并解析成RFC3164格式 * redis&#xff1a;从redis-server list中获取 * beat&a…