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

【Linux】初识信号

目录

一、人眼中的信号 VS 进程眼中的信号

二、Ctrl+C终止一个前台进程

三、signal函数--验证2号信号

四、查看信号信息

五、sigaction函数的三种处理动作方法

六、信号的处理方式

七、ctrl+c 被解释成2号信号验证

八、ctrl+c 是如何变成信号的?

九、初步理解信号

十、完结 


一、人眼中的信号 VS 进程眼中的信号

      人眼中的信号是什么样的?

      我们举个例子:当我们在马路上等红绿灯的时候,比如说正在等绿灯。

      在绿灯到来前(此时还没有绿灯),我们就先知道绿灯到来我们该干什么,这个叫做知道信号的处理方法。但是在知道信号的处理方法前,我们一定要先认识绿灯,这个叫做识别信号

      我们把这两个事物规定为:认识信号

      所以认识信号包括:识别信号和知道信号的处理方法。

      我们刚才说到过,即使信号没有产生,但我们依旧知道我们该怎么做,这一点很重要。

      信号产生了,我们可能并不立即处理这个信号,而是在合适的时机去处理,因为我们当前可能正在做更重要的事情,所以在信号产生后一直到信号处理前,有一个时间窗口,在这个时间窗口内,我们必须记住信号的到来


进程眼中的信号

      进程眼中的信号就像人眼中的信号一样

  • 进程必须能够识别、处理信号,即使信号没有产生,也要具备处理信号的能力。信号的处理能力,属于进程内置功能的一部分。
  • 进程即便是没有收到信号,也能知道哪些信号该怎么处理。
  • 当进程真的收到了一个具体的信号的时候,进程可能并不会立即处理这个信号,在合适的时候处理。
  • 一个进程必须当信号产生了,到信号开始被处理,就一定会有时间窗口,进程具有临时保存哪些信号已经发生了的能力。

      现在我们来实体化感受一下信号的存在

      用户输入命令,在Shell下启动一个前台进程

      用户摁下Ctrl+C,因此键盘的输入产生了一个硬件中断,被操作系统(OS)获取,但是OS并不能直接理解Ctrl+C是什么东西,所以操作系统把Ctrl+C解释成为信号,发送给目标前台进程

      前台进程因为收到信号,进而引起进程退出

未知名词解释:

前台进程:前台进程是指直接连接到当前终端会话、会占据终端输入输出,且在其运行期间,你在该终端里没法执行其他命令(除非它结束或被放到后台 )的进程

我们在终端里能直接看到它的运行状态(输出、等待输入等),且操作终端会直接影响它 

粗略理解就是我们可以在显示器上直接看到。

二、Ctrl+C终止一个前台进程

      我们刚才的图片中,使用的是Ctrl+C使这个程序停止运行的。

      它的本质其实是Ctrl+C终止掉1个前台进程。Linux中,一次登陆中,一个终端会配上一个 bash ,bash也是进程,每一登陆只允许1个进程是前台进程,可以允许多个进程是后台进程。

      在我们打开操作系统什么都没干时,bash就是一个前台进程。也就是说当你打开终端但没有运行任何其他程序时,bash 就是前台进程。

      例如我们在操作系统重输入指令:pwd,这时候bash就是前台进程,因为我们并没有运行其他任何程序

      但是我们在刚才的图片中,我们执行了自己的程序,这个程序是由bash创建的独立的一个新进程去运行的,所以此时bash就成为了后台进程(因为一个登陆的前台进程只能存在一个)

      那么图中的bash就成为了后台进程,此时再向 bash 中输入指令是没有任何反应的

      (一定是没反应,不是因为bash是后台进程我们看不到。因为我们的指令是在终端输入的,因此只有前台进程能接收键盘输入,后台的bash进程根本收不到)

如图:

      可以看见确实没有反应

      前台进程和后台进程的一个本质区别是,谁来获取键盘输入,只有前台进程才能拿到键盘输入。


      如果我们想让一个程序成为后台程序去运行,我们就需要这样写

./可执行程序 &

      后台进程运行如图:

      可以看到此时我们的Ctrl+C已经终止不了后台程序了。这里后台程序依旧可以被我们看到,是因为我们上面提到过,后台程序与前台程序的不同是谁来获取键盘输入,而不是谁能被用户看到。

      终止后台进程指令:

pkill 可执行程序名
//我们的例子中可执行程序名为red
//所以我使用的时pkill red

重点:

      ctrl+c 本质是被操作系统解释为 2 号信号。再将2号新号发送给进程,**进程收到2号信号的默认动作就是终止自己。


三、signal函数--验证2号信号

      我们在目录二的结尾提到了,Ctrl+C终止前台进程的本质是被操作系统识别为2号信号。

      那么接下来我们来验证一下它到底是不是2号新号

      这里要用到一个系统函数:

#include<signal.h>
sighandler_t signal(int signum,sighandler_t handler);
参数说明:
signum : 信号编号[后面会解释,现在只需要知道是个数字]
//第一个参数填写SIGINT代表由键盘输入产生的中断信号(后面会讲先短暂记住一下)
//第一个参数输入数字2代表自定义捕获信号编号为2的信号,以此类推handler : 函数指针。表示更改信号的处理动作,当收到对应的信号,就回调handler方法

      接下来我们实战用一下:

      可以看到,确实Ctrl+C的信号量是2

声明: 也可以写成 signal(2,handler);


四、查看信号信息

      信号是进程之间事情异步通知的一种方式,属于软中断

      名词解释:

      异步:信号的发送和接收是相互独立、不同步进行的。

也就是说我发送信号不管你能不能接受,只要我满足信号发送的条件,就直接发送信号

接受也是同理


      软中断:软件层面产生的硬件中断,用于通知进程处理特定事件

举个例子:你在家里看书,突然门铃响了,你就不得不放下书去看一下是谁来了

      软件层面产生硬件中断解释:

      例子 1:程序出错时,操作系统自动发信号(软中断)

你的代码中出现 a/0 ,不可以除0,所以程序出错了,发送信号。

      例子 2:用命令手动给进程发信号(软中断)

      假设你在终端运行./myprocess,然后打开另一个终端输入:

      kill -10 12345 # 12345是myprocess的进程ID

      这个命令会给myprocess发送信号,此时如果myprocess在处理其他事情,就会暂停当前工作去执行处理逻辑。

      这里我们介绍几个常用的指令:

      pidof myprocess:显示操作系统中所有 myprocess 进程的 pid。

      pidof myprocess | xargs kill -9:杀掉当前操作系统启动的所有 myprocess 进程。

      kill -l:查看系统的信号列表。

      信号没有0、32、33号信号,一共有62个信号。1-31号称为普通信号;34-64号称为实时信号,进程一旦收到实时信号,必须立即处理。

      信号本质上就是数字,右边的字符是信号的名称,在操作系统的内核中,信号一定是以宏定义的方式提供的,这些宏定义在 signal.h 中可以找到。

在宏定义找到:

#define SIGINT 2

以此类推

      再介绍一个新的指令:

      man 7 signal:查看信号的详细说明。

      其中 TermCore 表示终止;Ign 标记忽略;Cont 表示继续;Stop 表示暂停。


五、sigaction函数的三种处理动作方法

1. SIG_IGN 忽略此信号

      signal的第二个参数: SIG_IGN 可以忽略信号,可见我们输入Ctrl+C后并没有终止进程,而是忽略了


2.SIG_DFL 执行该信号的默认处理动作


3.自定义信号处理函数

      我们最开始展示的就是自定义了信号处理函数(函数handler),这种方式叫做自定义捕捉一个信号


六、信号的处理方式

      进程收到信号有三种处理方式,这三种处理方式就是我们刚才所演示的三种

  • 默认动作:人看到红灯,默认动作就是站在原地,等待红灯结束。
  • 忽略:人看到红灯之后,不管红灯,继续往前走。
  • 自定义动作(信号的捕捉):人看到红灯后,开始唱歌。

      进程收到一个信号后,它的处理动作只能在上面这三个动作中进行三选一。


七、ctrl+c 被解释成2号信号验证

5.1 signal——设置自定义捕捉方法

      signal——设置进程对某个信号的自定义捕捉方法:当进程收到 signum 信号的时候,去执行 handler 方法。

      signum:信号的编号。
      handler:一个函数指针,指向信号的自定义捕捉动作。
      sighandler_t:一个函数指针类型,指向一个返回值为 void 参数为 int 的函数,这个参数值就是收到的信号。为什么要有这个参数呢?因为同一个自定捕捉方法,可以捕捉多个不同的信号,所以在该方法中需要知道是收到哪个信号才来执行的该方法。

      signal 函数只需要设置一次,往后都有效。sighandler_t 函数只会在收到对应的信号后才会执行,假如程序一直没有收到对应的信号,那么该函数就一直不会被调用。

      这里不演示了,因为我们之前一直在用的就是signal这一个函数


八、ctrl+c 是如何变成信号的?

      由于进程无法访问硬件资源,所以当我们摁下键盘后,一定是操作系统先知道的。

      但是操作系统怎么知道我们摁的是什么的?

      在数据层面,CPU 是不会直接和外设打交道的。

      但是在控制层面,当外设有数据了,外设可以给 CPU 发送硬件中断中断都有自己的中断号,硬件中断就是这样,CPU 通过它的中断号来判断该中断是哪个外设发送的。之后 CPU 会以这个中断号为下标,去操作系统的中断向量表中执行对应的方法(也就是执行所对应的程序),接着这个程序会将中断向量表所对应的硬件数据读取到内存中。

      当操作系统识别到这些特殊数据后,不会将数据拷贝给目标进程。而是转化为向目标进程发送信号,从而将目标进程退出或暂停等行为!

      (名词解释: 硬件中断:硬件中断不是信号,是信号产生的源头之一)

      操作系统在将硬件数据拷贝到内存之前,会先判断输入的是数据还是控制,如果是控制,ctrl+c 就是控制,会被操作系统转换成2号信号并直接发送给进程,让进程按默认规则(通常是终止)响应。

小Tips:键盘和显示器有各自独立的文件页缓冲区

九、初步理解信号

      信号其实是从纯软件角度,模拟硬件中断的行为,只不过硬件中断是发给CPU的,而信号是发给进程的,两者有相似性,但是层次不同

十、完结 

http://www.dtcms.com/a/537706.html

相关文章:

  • 网站优化常见的优化技术wordpress内置函数
  • HGDB5.6.5集群备机手动switchover提示data目录无效
  • 网站开发品牌做网站 零基础从哪里开始学
  • 【Rust编程:从新手到大师】Rust变量深度详解
  • asp.net网站开发与应用无极在线房屋出租信息
  • 一键部署 Deepseek网页聊天系统(基于 Spring Boot + HTML 的本地对话系统)
  • 那个网站都有做莱的图片湖北响应式网站设计制作
  • 一家专做二手手机的网站叫什么手机网站开发与建设的原则
  • 前端可视化工具推荐
  • 建筑网站设计方案手机如何制作网站和网页
  • 鞍山百度做网站网络推广软文怎么写
  • Vue3 响应式系统深度解析:Proxy 为何能替代 Object.defineProperty?
  • 忻州网站建设有些电影网站是怎么做的
  • 兰溪网站建设公司经营性质的网站
  • 项目实践5—全球证件智能识别系统(Qt客户端开发+FastAPI后端人工智能服务开发)
  • 苏州网网站建设企业网站源码带后台
  • 做学术研究的网站惠州市住房和城乡建设厅网站
  • iis应用程序池 网站塘沽网站制作公司
  • 海外网站哪个最好沈阳网站建设58同城
  • ArcGIS Pro与Python下空间数据采集与管理
  • 单片机跑飞原因及解决方法
  • 什么是网站交互全国最大工地招工网
  • 推广网站有哪些平台海外运营工作内容
  • 响应式网站开发 三合一建站备案后修改网站名称
  • 佘山做网站wordpress底部footer
  • 哪个网站做漂流瓶任务做网站外国的
  • 可以做设计赚钱的网站外包公司辞退员工补偿标准
  • 网站共享备案可以申请支付接口网站维护协议
  • 信息技术应用创新 | 基于KylinV10的达梦数据库DM8基本操作
  • 如何租用服务器做网站温州做网站公司