云计算百科
云计算领域专业知识百科平台

Linux 进程信号深度解析:从内核机制到实操应用全指南----《Hello Linux!》(15)

文章目录

  • 前言
  • 信号的初步认识
    • 捕获信号的办法
    • 键盘数据输入给内核的原理
    • core dump
  • 信号的产生
    • 系统调用
    • 异常
    • 软件条件
  • 信号的发送
  • 信号的保存

前言

在 Linux 系统中,进程信号是一套高效的 “异步通信机制”—— 它如同给进程发送的 “通知”,能够打断进程的正常执行流程,触发预设的处理动作。小到ctrl+c终止前台进程,大到异常崩溃时的核心转储(core dump)、进程间的紧急通知,信号贯穿了 Linux 进程管理的方方面面。

信号的本质是内核向进程传递事件的 “软件中断”,其生命周期涵盖 “产生→发送→保存→递达→处理” 五大环节,背后依赖block(阻塞)、pending(未决)、handler(处理函数)三张核心表的协同工作。本文将从基础认知出发,层层拆解进程信号的核心逻辑:先讲信号的三种处理方式、前台 / 后台进程与信号的关联,再深入信号捕获的signal系统调用、键盘输入触发信号的底层原理;随后详解信号的五种产生途径(键盘、命令、系统调用、异常、软件条件),并剖析内核中信号的保存机制与阻塞 / 未决状态的核心概念;最后结合core dump调试、信号位图管理等实操技巧,帮读者打通 “理论原理” 与 “实际应用” 的壁垒。

无论你是刚接触 Linux 进程编程的新手,还是想深入理解内核信号机制的开发者,都能通过本文掌握信号的核心知识点 —— 包括不可捕获 / 阻塞的 9 号(SIGKILL)与 19 号(SIGSTOP)信号、原子操作的信号位图、alarm闹钟信号等关键细节,轻松应对进程中断、异常处理、进程间简单通信等实际开发场景。

信号的初步认识

1.进程必须要能识别和处理信号–就算这个信号没有被产生,进程也需要具备处理这个信号的能力

–对信号的处理能力,属于进程的内置功能

2.进程没有收到信号,也能知道这些信号的处理方法是什么

3.当进程真的收到了信号,进程可能不会立马处理这个信号,而是等到合适的时候处理

4.进程具有临时保存哪些信号发生了的能力

–因为信号产生到信号被处理之间会有时间窗口

信号的处理方式有三种:(只能三选一哈)

1.默认动作 2.忽略 3.自定义动作(比如:捕捉这个信号)

在Linux中,一次登陆就会有一个终端,一个终端一般只有一个bash;一个bash的话就只允许一个进程是前台进程,但是可以有多个进程是后台进程

在这里插入图片描述 这样的话算两次登录哈

把进程搞成后台运行的方法:最后加个& eg:./a.out &

注意:只有前台进程才能获取键盘输入 –前台进程搞成其他了的话,bash就用不了了

但是前台和后台进程都能显示到显示器上哈

ctrl+c只能杀掉前台进程,不能杀后台进程

捕获信号的办法

在这里插入图片描述

1到31的信号称为普通信号(掌握这些就就行了)

后面的称为实时信号

eg:SIGHUP这些是宏,其实就是1

想要知道这些信号是干啥用的:man 7 signal可以查询eg:信号的默认处理动作

在这里插入图片描述

这个系统调用接口可以用来捕捉信号–程序里只需要设置一次,往后都有效(但是进程结束了也就没了哈)

这里面的handler是用来修改特定进程对于信号的处理动作的,也可以设置成eg:SIG_IGN这样的(这是信号处理动作的宏定义)

信号处理动作的宏定义:

1.SIG_IGN:忽略该信号

2.SIG_DFL:使用系统默认的信号处理动作

–也就是用来改当前进程的handler表

使用方法:

void myhandler(int signo) signo是读取到的信号的编号
{....里面可以对这个东西做处理}

signal(SIGINT,myhandler)//写成signal(2,myhandler)是一样的

注意:不是所有信号都能被signal捕捉到的,在普通信号里面9和19是不行的

键盘数据输入给内核的原理

键盘上有按键输入时会产生硬件中断(通过中断号和中断单元通知CPU),CPU通过中断向量表找到处理问题的方法,然后OS就会接管并执行对应的处理中断的程序

这个中断向量表是OS维护的哈,里面存的是处理中断的那些方法的地址

执行中断的程序:比如:ctrl+c这种特殊组合键,就被OS处理成了信号

普通按键的话就被搞入系统缓冲区,然后给用户缓冲区…..

直接访问外设的方式,主要是磁盘,显示器,键盘

CPU保存数据的原理:给寄存器的针脚发送高低电平信号

信号其实就是用软件方式,对进程模拟的硬件中断(但不是真的硬件中断哈)

引申:键盘回显到显示器,如果显示器上还要其他数据显示,是不会打乱输入的:

因为键盘的输入是存在自己的缓冲区里面的,只是把这部分数据拷贝了一份给显示器的缓冲区而已

不同的文件会使用不同的缓冲区

core dump

core dump:核心转储

用法:开启gdb调试器之后,core-file core.pid文件 ,然后就会给出出错行是哪个以及报错的信息

SIGINT和SIGQUIT的区别就是SIGQUIT除了终止进程,还会core dump

一个进程异常终止时,如果信号的Action是Core的话,OS会将进程在内存中的运行信息转储到进程的当前目录(和进程同一级哈)里面形成core.pid文件 比如core.30238

是core的话,进程状态那个core dump那个位置就是1

在默认情况下,云服务器的core功能是关闭的–害怕挂起之后又运行,这样就会产生很多个core.pid文件,这个文件的大小又很大

一些相关的指令:

ulimit -a:列出当前用户所有的进程资源限制配置(比如:核心转储文件大小的限制)

ulimit -c:显示核心转储文件大小的限制

ulimit -c m:把核心转储文件大小的限制改成m(比如1024)–改成非0的,也就开启了core功能

信号的产生

信号的产生和代码的运行是异步的

也就是说,信号可以在代码执行的任何时刻产生

信号的产生常见的方法有五种:

1.键盘组合键 eg:ctrl+c 产生的就是2号信号

2.kill命令 kill 信号的号数(比如2) 给哪个进程(填pid)

3.系统调用

4.异常

5.软件条件

系统调用

主要有kill raise abort

kill:

在这里插入图片描述

sig就是要填几号信号

返回值:成功返回0,失败返回-1

raise:这个的话是对调用者(当前进程)发信号

在这里插入图片描述

返回值:成功返回0,失败返回非0值

abort:

在这里插入图片描述

这个的话是给当前进程发送SIGABRT信号(也就是6号信号)

但是这个跟直接给这个进程发送6号信号有点不一样

调用了abort的话,这个信号被捕获了之后,程序还是会被终止(kill raise不行哈)

异常

比如:野指针时会让进程崩溃–因为产生了段错误,发送了11号信号

–这种的如果用signal改了行为的话,就会一直发送11号信号

如果此时进程不崩溃的话,这个进程就一直会被调度运行–但是一调度就会被挂起(因为一直出问题)

–也就是出异常了,操作系统不会直接把这个进程给干掉

这是OS给进程发送的信号

–过程:CPU里面存的是虚拟地址,然后交给MMU(内存管理单元)转换成物理地址;但是比如野指针就会导致地址转换失败,触发硬件异常,然后OS就知道有问题了,就会…

引申:1.OS是硬件的管理者

2.进程对CPU寄存器的修改操作,只会影响自身进程–因为进程的上下文机制

3.现在MMU一般在CPU内部

异常不是只有硬件会产生,软件也是会的

比如:管道的读端关闭了,写端还在继续写,这个时候就会异常

软件条件

比如:闹钟alarm

闹钟不是异常,是系统层面的一种软件条件

alarm:时间到了会发送14号信号

在这里插入图片描述

seconds:想多少秒之后触发就写多少

返回值:返回的是上一次的闹钟还有多久触发(已经触发了的话,返回的是0)

闹钟是设置多少次就响多少次–跟signal区分

信号的发送

对于普通信号,进程会记录有没有收到信号,收到的是哪种信号

用的是位图去管理(接收到这个信号,就那个位置变为1)–相同的多个信号还没被处理的话,最后也就被处理一次

如果是实时信号的话,需要立即处理,而且接收到几次就要处理几次

这里的发送信号,本质是OS去修改task_struct的信号位图对应的比特位

–因为OS是进程的管理者,只有它有资格去修改task_struct内部的属性

信号的保存

为什么需要保存信号?–信号被进程接受后,并不一定立即处理,这时就需要有一个时间窗口

在这里插入图片描述

信号是几号,那它对应的block pending handler下标就是几

block里面为1,表示信号被阻塞

pending里面为1,表示信号未决

handler里面存的是处理方法的地址

信号保存的话,要保存它的block状态 pending状态

block(阻塞,也叫屏蔽):被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作 —信号还没产生,就可以先把这个信号block了

–9号信号SIGKILL和19号信号SIGSTOP不能被阻塞

pending(信号未决):信号从产生到递达之间的状态

信号递达:实际执行信号的处理动作

对于1-31号的信号pending的位图,多久从1变成0:

在执行信号捕捉方法之前变 是先清0,再调用信号捕捉函数

赞(0)
未经允许不得转载:网硕互联帮助中心 » Linux 进程信号深度解析:从内核机制到实操应用全指南----《Hello Linux!》(15)
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!