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

Re:Linux系统篇(四十三)信号篇·一:谁在敲进程的门?一篇带你了解信号概念与产生机制

◆ 博主名称: 小此方-CSDN博客
大家好,欢迎来到小此方的博客。
⭐️Linux系列个人专栏: 【主题曲】Linux
⭐️此方的GitHub: github_此方
⭐️Re系列专栏:我们思考 (Rethink) · 我们重建 (Rebuild) · 我们记录 (Record)

文章目录

  • 概要&序論
  • 一、信号的概念
    • 1.1感性理解信号的概念
    • 1.2如何查看所有的信号
    • 1.3综上得出关于信号的基础结论
  • 二、信号的产生
    • 2.1键盘产生信号
      • 2.2.1信号处理的三种抉择与自定义信号处理
      • 2.1.2如何验证键盘产生了信号以及产生了何种信号
    • 2.2目标进程是什么?
      • 2.2.1如何切换进程的前后台
      • 2.2.2后台进程不响应键盘的输入
    • 2.3给进程发送信号的本质是什么
    • 插曲:讲一讲前台进程组的概念
      • 2.3.1 什么是进程组?
      • 2.3.2 Ctrl + C 的批量传递机制
    • 2.4系统调用和系统命令产生信号
      • 2.4.1系统调用kill发送信号
      • 2.4.2系统调用raise发送信号
      • 2.4.3系统调用abort发送信号

概要&序論

Hello,大家好我是此方,结束进程间通信,来到了Linux的倒数第二个话题——信号。今天主要介绍信号的基础认知以及信号是如何产生的等问题。好,我们开始吧。

一、信号的概念

1.1感性理解信号的概念

我们在先前讲到过信号量的概念,但是今天我们要讲的信号,和信号量的关系就像老婆和老婆饼,雷锋和雷锋塔——毫无关系

信号与IPC的辩证关系

闹钟响了你要起床,绿灯亮了你要通过,在这些语境中,闹钟和绿灯都是信号。信号中断了人正在做的事情——因为你有新的事情要做了!那么,把人换成进程,信号就是中断进程当前任务的“异步通知机制”。
详细解释:”异步“——说的是信号的发送过程相对于进程的执行是异步的。

李老师在上课,突然由通知让李老师去拿卷子,李老师派小刚去拿卷子。“好的孩子们,我们先自习一会儿,等小刚回来我们再上课”——同步。“好的孩子们,我们不等小刚,继续上课,小刚在执行拿卷子,李老师同时在执行上课”——异步。

1.2如何查看所有的信号

我们有哪些信号?通过指令kill -l来查看。信号就是一个整数数字一个宏,我们一共有62个信号。其中前31个信号是普通信号,后31个是实时信号,本篇重点讲解普通信号。

  • 1-31普通信号不必立即处理。
  • 34-64实时信号必须立即处理。

信号在源代码中

详细看到每一个信号的细节,可以用man 9 signal查看:

从左向右依次是信号的名称,信号遵循的标准版本,信号的默认行为,信号的行为详细信息。

信号的默认行为有:终止(Term)核心转储(Core)停止(Stop)忽略(Ign)。具体放在后续详细讲解。

1.3综上得出关于信号的基础结论

  • 进程在信号没有产生的时候,早就知道信号该如何处理了。——你知道红灯亮了要停车,绿灯亮了要前进。
  • 信号的处理,不是立即处理,而是可以等一会在处理,合适的时候,进行信号的处理。——你在直播游戏,外卖到了你必须记住这个信号,然后在这局游戏结束后下楼取外卖
  • 人能识别信号,是提前被"教育"过的,进程也是如此,OS程序员设计的进程,进程早已经内置了对于信号的识别和处理方式。
  • 生活中的信号源非常多->给进程产生信号的信号源,也非常多!(信号源有哪些我们后面讲。)

于是我们接下来的三篇关于信号的文章,主要以以下这条线叙事。信号产生,捕捉,保存,处理。

二、信号的产生

2.1键盘产生信号

信号产生的方式有很多种,键盘产生信号就是其中之一,我们以前使用的CTRL + C 就通过产生信号来终止进程。

2.2.1信号处理的三种抉择与自定义信号处理

验证前须知:收到信号的处理动作有默认处理,自定义处理和忽略处理三种抉择。如何进行自定义处理?

自定义信号处理的系统调用signal通过传入函数指针进行回调。返回值:

  • 成功时:返回该信号上一次关联的处理函数(handler)的值。例如,如果该信号之前的处理方式是 SIG_IGN,那么返回值也会是 SIG_IGN。
  • 失败时:返回 SIG_ERR,并且会将全局变量 errno 设置为相应的错误原因(如 EINVAL,表示信号无效)。

科普
操作系统在设计的时候,为了防止恶意进程通过篡改信号处理机制使得其无法被任何手段暂停和终止。不允许9号和19号信号被设置自定义处理

2.1.2如何验证键盘产生了信号以及产生了何种信号

你想怎么验证?我想看到信号处理的过程——通过修改信号处理的默认操作。代码如下:

#include<iostream>#include<string>#include<signal.h>#include<unistd.h>voidHander(intn){std::cout<<"收到信号:"<<n<<std::endl;exit(1);}intmain(){for(inti=0;i<32;i++)signal(i,Hander);while(1){std::cout<<"进程运行中。。。"<<std::endl;sleep(1);}return0;}

运行,当我们按CTRL+C的时候,进程接收到信号2并打印,当我们按CTRL + \ 进程收到三号信号并打印。

2.2目标进程是什么?

回归定义截取——”信号是发送给目标进程的“ ,那么目标进程是什么呢?直接说答案:前台进程。后台进程可以有很多个,但是前台进程只能有一个。
键盘知道它自己要把信号发送给哪个进程吗?——唯一指向前台进程。前台进程的一个本质就是可以从键盘中获取数据的进程。

  1. 前台进程可以获取标准输入的内容。
  2. 后台进程不可获取标准输入的内容。
  3. 两者都可以向标准输入写入内容,
科普
在 Windows 操作系统中,我们看似能同时看到浏览器、文档等多个窗口在“前台”并存但这只是视觉上的多任务。由于键盘只有一个,Windows 引入了“输入焦点”机制。本质上,只有被你用鼠标点击选中的那个当前活跃窗口,才是唯一真正的“前台进程”,独占键盘的输入数据;而其他未被选中的窗口,哪怕肉眼可见,在输入层面也属于“后台进程”,无法获取你的键盘敲击。这与 Linux 终端下前台进程只有一个的底层逻辑完全一致。

2.2.1如何切换进程的前后台

方法一:在运行进程的时候在后面加上取址符。

# ./XXX --- 前台进程# ./YYY & --- 后台进程

方法二:指令操作。

jobs: 查看所有的后台任务。
fg 任务号: 特定的进程,提到前台。
ctrl+z:进程切换到后台。(暂停进程,暂停的进程必须被切换到后台)
bg 任务号:让后台进行回复运行。

2.2.2后台进程不响应键盘的输入

这里举两个常见的案例:我们./proc执行一个死循环打印的进程,此时我们载用键盘输入指令ls ,shell不会回应,因为shell从前台切换到了后台。
父进程提前退出,子进程孤儿化,被操作系统切换到后台进程,此时响应不了键盘,无法通过ctrl+c杀掉

2.3给进程发送信号的本质是什么

一个信号发出去,不会立即处理而是存起来对不对?那么存在那里呢?在进程PCB中有这么一个字段:

structtask_struct{unsignedintsigs;}

这是一个32位的位图,刚好可以存放31个信号的二元状态信息。

  • 位的位置标识哪一个信号。
  • 位的0/1标识信号是否被收到。

所以我们就可以知道,信号发送的本质就是:修改为位图。

联系起来:我们的键盘输入ctrl+c,操作系统作为硬件的管理者,识别出ctrl+c是发送信号。于是将这个信号写入前台目标进程的位图,前台目标进程在指定的时间查看自己的位图是2号信号,杀掉自己。
好,继续回来,unsigned int sigs;在task_struct ,它属于操作系统的数据结构对象,修改数据本质就是修改内核数据。而修改内核数据必须要通过系统调用——不管信号如何产生,在底层必须通过系统调用发送信号。所以我们引出kill:(跳转到2.4

插曲:讲一讲前台进程组的概念

在理解了前台进程后,我们往往会产生疑问:既然前台进程“有且仅有一个”,那为什么按下Ctrl + C时,前台的父子进程会同时挂掉
其实,操作系统底层的精确表述是:当前终端有且仅有一个“前台进程组”

2.3.1 什么是进程组?

在 Linux 内核中,进程是“抱团”运行的。每当我们在终端启动一个程序,系统就会分配一个进程组 ID(PGID)

  • 组长进程:由命令行直接启动的父进程担任,其 PID 就是整个进程组的 PGID。
  • 组员进程:父进程通过fork()创建的所有子进程,默认都会自动加入该进程组,共享同一个 PGID。

终端在管理输入和信号时,正是以“进程组”为单位进行独占和调度的。

2.3.2 Ctrl + C 的批量传递机制

当操作系统识别出Ctrl + C的 2 号信号(SIGINT)后,它在底层并不是发给某个单一的 PID,而是直接锁定当前处于前台的整个进程组
随后,内核会遍历该前台进程组内的所有进程(含父进程和所有子进程),将信号分别写入它们各自 PCB 的信号位图中。父子进程在各自的调度时机检测到信号后同时执行退出。

2.4系统调用和系统命令产生信号

系统调用和系统命令是产生信号的第二种方式。主要的系统调用有kill,raise,abort。系统命令主要是kill。系统命令kill我们一直在用就不讲了

2.4.1系统调用kill发送信号

#include<iostream>#include<sys/types.h>#include<signal.h>#include<unistd.h>voidHander(intx){std::cout<<"捕捉到信号"<<x<<std::endl;}intmain(){for(inti=1;i<32;i++)signal(i,Hander);for(inti=1;i<32;i++){kill(getpid(),i);sleep(1);}return0;}

2.4.2系统调用raise发送信号

专门给自己发送信号的系统调用。raise(sig) 等价于kill(getpid(),sig);

#include<iostream>#include<sys/types.h>#include<signal.h>#include<unistd.h>voidHander(intx){std::cout<<"捕捉到信号"<<x<<std::endl;}intmain(){for(inti=1;i<32;i++)signal(i,Hander);for(inti=1;i<32;i++){raise(i);sleep(1);}return0;}

2.4.3系统调用abort发送信号

注意是abort不是about

异常终止当前进程,并产生一个 Core Dump(如果系统允许),abort() 会向自己发送 SIGABRT 信号。


我们发现Hander无法组织abort结束进程。为什么?因为POSIX 对 abort() 有明确规定:如果 SIGABRT 被捕获,并且处理函数返回,abort() 必须仍然终止进程。

Gemini对此提供了一个不错的解释:

还没有讲完,下一篇将带大家了解另外两种信号产生机制


好的本期内容就到这里,如果对你有帮助,还不要忘记点赞三联支持。我是此方,我们下期再见。bye! Linux、C++、算法持续连载中,欢迎关注WeChat Official Account 【此方的技术栈】。
http://www.jsqmd.com/news/1195763/

相关文章:

  • 美度中国官方售后服务中心|服务热线及全部官方地址权威信息声明(2026年7月最新) - 亨得利官方服务中心
  • 如何快速打造个人漫画图书馆:哔咔漫画下载器终极指南
  • 从浴盆曲线到智能预测:可靠性工程在现代产品生命周期中的实践演进
  • icoding数据结构——块链串子串查找算法实现与边界陷阱解析
  • 毕设开源 机器学习的垃圾邮件分类系统(源码+论文)
  • 史诗级对决!Claude 4.8 惨虐 GPT-4o?测试结果让人意外!
  • 多分类混淆矩阵与TP/FP/FN/TN逐类计算原理
  • 劳力士中国官方售后服务中心|官方地址及售后服务热线权威信息公告(2026年7月最新) - 劳力士服务中心
  • 从零到一:用Arduino Uno打造你的第一台智能巡线小车
  • SQLite和Java:使用Java打开SQLite数据库-元一软件
  • 零基础想学网安,第一个月该把时间花在哪
  • 2026惠州惠阳黄金回收权威评测:全域覆盖S级资质首选,惠奢汇(惠阳店)领跑本地市场 - 生活测评小能手
  • 【几何与代数】从投影到扭矩:向量内积与外积的物理世界解读
  • 技术解析:前方交通穿行提示与制动(FCTA/FCTB)如何与ESP/ABS协同保障低速安全
  • 【独家披露】头部AI实验室内部使用的ChatGPT数据增强协议:含12类任务模板+自动去偏算法+人工审核阈值表
  • 龙卷风EF强度分级解析:从EF0到EF5的破坏力与防护指南
  • Java包管理与字符串操作实战:从项目结构到数据处理
  • 终极指南:5分钟永久激活Adobe全家桶的免费神器
  • 欧米茄发条怎么用?售后维修保养指南权威公示(2026年7月最新) - 欧米茄服务中心
  • 网络热梗识别技术:基于BERT与知识图谱的内容审核实战
  • 仅限内部团队流传的Cursor筛选秘钥:8个未公开的@指令与#context标记,大幅提升TypeScript项目检索准确率
  • Grok模型技术解析:架构、性能与应用实践
  • 个人财务健康诊断系统:Bank Scan轻量级落地实践
  • AI 导出鸭实操教程:怎么把 Gemini 生成的表格导出,一站式搞定多格式转换难题
  • 2026惠州黄金回收白名单:本地人亲测、无套路的五家正规回收门店 - 资讯纵览
  • 麒麟V10系统安装达梦数据库
  • Claude 4.8 适合写营销文案吗?从产品卖点到用户痛点的爆款生成教程
  • connectwise-sell-mcp MCP 服务说明文档
  • 识图谱在智能工厂应用
  • 【合肥理工学校】招生电话是多少?住得好不好,吃得好不好? - zshll