《Linux 信号入门:搞懂 “进程通信的紧急电话” 到底怎么用(初篇)》

《Linux 信号入门:搞懂 “进程通信的紧急电话” 到底怎么用(初篇)》
前引:在 Linux 系统中,信号是进程间 “即时通信” 的核心机制 当你用 Ctrl+C 终止程序、用 kill 命令结束进程,本质都是信号在发挥作用。很多开发者入门时觉得信号 “简单”,实际编程时却常踩坑:信号丢失、处理函数重入、竞态条件等问题屡见不鲜。本文将从信号的本质出发,拆解核心原理、常用接口与实战技巧,帮你彻底搞懂信号,避免在进程通信中踩雷!

目录

【一】信号初识

(1)什么是“信号”

(2)“信号”查看

(3)补充:数据从键盘到显示器

【二】发送信号

(1)指令发送

(2)键盘发生

(3)系统调用

(1)kill()最常用

(2)raise()

(3)abort()

(4)异常(硬件发送)

(5)信号(软件发送)

【三】操作系统如何发信号


【一】信号初识

(1)什么是“信号”

“信号”是什么?

“信号”用来给某个进程直接传达的命令,因此“信号”的发出对象为操作系统

那么每个进程都应该知道信号实行的方法。按照理论:被接收“信号”的受体可以选择:

“默认执行”:直接按照信号的实现方法默认执行

“不执行”:选择无视信号

“自定义执行”:不顾具体的信号实行方法,自己按自己的方法实行
(2)“信号”查看

可以执行下面的命令查看所有的信号:可明显发现数字序号和对应的大写字符串其实是宏实现的

kill -l

其中:1~31号信号为普通信号,34~64号信号为实时信号(暂时不了解)

(“Ctrl+C”在我们进程死循环时可以强制退出,它对应的实现是 2号信号)

在Linux中,会存在前台进程和后台进程:

前台进程:直接展现给用户的(默认打开的是 bash 进程),每次登录只能允许一个前台进程存在

后台进程:隐藏起来执行的进程

(3)补充:数据从键盘到显示器

我们知道操作系统和硬件之间夹着“驱动程序”,键盘输入时对应的“驱动程序”会发生“中断请求”给CPU,CPU接到请求知道了有数据需要从“键盘”读取,它会让操作系统拿数据到对应“缓冲区”,待操作系统有时间处理(感觉就是进入运行队列!)就会刷新到“显示器文件”,“显示器”拿到了数据

【二】发送信号

在学习发生信号的方式之前,我们需要先看一下另一个接口:signal()

(注意:9号信号“强制终止”19号信号“强制暂停”是无法被替换执行方法的)

#include <signal.h> // 信号处理函数类型定义(参数为信号编号) typedef void (*sighandler_t)(int); // 注册信号处理函数 sighandler_t signal(int signum, sighandler_t handler);

参数:

第一个参数:信号

第二个参数:函数指针(用来自定义一个函数作为参数)

作用:执行该接口后,该信号默认执行方法失效,捕捉该信号执行自定义执行方法(即该函数)

           当捕捉到 2 号信号,也就意味着原来 2 号信号的执行方法将不再生效!

例如:

返回值:暂时不关心

(1)指令发送

指令发送即执行:指令发送我们就不多谈了,实行 kill 指令与选项即可

kill -序号 进程ID
(2)键盘发生

比如:Ctrl+C(对应2号信号)、Ctrl+\(对应3号信号)

(3)系统调用

下面介绍三个可以发送信号的系统调用接口:你会发现最后两个接口都可以通过 kill()实现!

(1)kill()最常用
#include <signal.h> #include <sys/types.h> int kill(pid_t pid, int sig);

参数:

第一个参数:目标进程

第二个参数:要发送的信号编号

返回值:

  • 成功:返回0
  • 失败:返回-1,并设置errno

作用:给指定进程发送对应的信号

例如:

(2)raise()
#include <signal.h> int raise(int sig);

参数:信号编号

返回值:

  • 成功:返回 0
  • 失败:返回非 0(设置errno)

作用:向正在运行的(即调用该函数的进程)进程发送信号

例如:

(3)abort()
#include <stdlib.h> void abort(void);

参数:无

返回值:无

作用:触发程序的异常退出(发送6号SIGABRT信号)

例如:

(4)异常(硬件发送)

比如代码中出现除0错误,对空指针解引用....下面我们来梳理该类错误的产生过程:

CPU中会存在程序计数器(比如PC指针)用来找到下一行代码(不会干扰其它进程),当CPU知道下一句代码指令是违规的(可能是语法规定有被解析到),就会暂停执行代码,告诉操作系统错误情况(比如错误位置、原因等等),操作系统拿到CPU的反馈错误后再通过信号向该进程发送,用户再通过提示知道错误信息,一般出现信号错误都是很严重的错误,进程会终止,但是在大型的服务器上,会循序重新执行程序,只给你报错误信息!


了解即可:错误信息其实是被保存在 core dump文件(这个是需要手动开启)
难道异常都是由硬件发出吗?当然不是软件也可以,请继续向下看:
(5)信号(软件发送)

以 alarm()函数为例:给当前程序定一个闹钟(到时发送SIGALRM-14号信号

#include <unistd.h> unsigned int alarm(unsigned int seconds);

参数:设置的秒数(比如5秒,seconds=5)

返回值:上一次设置的定时器剩余的秒数(混淆点)比如:

第一个alarm()函数的返回值应该是0,因为它之前没有闹钟

如果有多个alarm():前一次调用alarm设置的定时器 “还没到期”(还没触发 SIGALRM 信号)时,再次调用alarm。就会覆盖前面的秒数直接执行当前alarm()

例如:

我先设置一个闹钟,alarm(20),然后观察返回值以及验证是否发送的是14号信号:

结果:我发送了两次14号信号,被正常捕捉没有问题。但是20秒后闹钟响了又被捕捉到了

下面验证如果存在多个alarm(),是否会覆盖旧的闹钟秒数:

【三】操作系统如何发信号

操作系统给这个进程发信号,实质是修改 task_struct 中的 int signal 参数:

Read more

Flutter 三方库 modular_core 大型应用级鸿蒙微服务化架构适配解析:纵深拆解路由控制组件化隔离网格,利用轻量级依赖注入中枢斩断应用深层耦合羁绊-适配鸿蒙 HarmonyOS ohos

Flutter 三方库 modular_core 大型应用级鸿蒙微服务化架构适配解析:纵深拆解路由控制组件化隔离网格,利用轻量级依赖注入中枢斩断应用深层耦合羁绊-适配鸿蒙 HarmonyOS ohos

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 modular_core 大型应用级鸿蒙微服务化架构适配解析:纵深拆解路由控制组件化隔离网格,利用轻量级依赖注入中枢斩断应用深层耦合羁绊 在构建超大型、多业务线的鸿蒙应用时,代码的模块化分层与解耦是决定项目成败的关键。modular_core 作为 flutter_modular 的核心逻辑库,提供了一套纯粹的依赖注入(DI)和模块生命周期管理机制。本文将深入解析该库在 OpenHarmony 上的适配与应用实践。 前言 什么是 modular_core?它不是一个 UI 框架,而是一套管理“对象如何创建”和“模块如何组织”的底层协议。在鸿蒙操作系统这种强调模块化分发(HAP/HSP)和细粒度原子化服务的生态中,利用 modular_core 可以帮助开发者构建出高内聚、低耦合的系统底座。本文将指导你如何在鸿蒙端侧实现模块的动态注入与回收。 一、

By Ne0inhk
地瓜机器人智慧医疗——贰贰玖想要分享的关于使用惯导的一些思路

地瓜机器人智慧医疗——贰贰玖想要分享的关于使用惯导的一些思路

前言 在第20届全国大学生智能车竞赛(智慧医疗机器人创意赛)中,我们贰贰玖拿下国一。在这里,作为队长兼技术主力兼机师兼……我想分享一下在备赛过程中的一些思路。当然,为了不把比赛搞成全都是20s以内,竞争激烈到前后几名差0.几秒,我不会开源我们的惯导和避障思路(实在太简单,太容易实现了)。 这是我们两年的备赛日记,也有我们第二年区域赛和国赛的全流程。 【贰贰玖|从省三到国一,从巡线到路径规划到惯导+纯视觉避障的贰贰玖智能车日记-哔哩哔哩】 https://b23.tv/IDJyM2P 数据集我放在这里了,一共2w9张,全都是640x480,有数据增强的(没有旋转):https://pan.baidu.com/s/10u4S4fiVATRyEeDpdzpk_A?pwd=0229 提取码:0229 下面面我会讲一下我们的网络问题怎么解决,上位机的一些辅助处理,如何半场扫码,如何准确返回 P 点,修改stm32,以及修改车的ekf.yaml。

By Ne0inhk
Windows 安装 Neo4j(2025最新·极简)

Windows 安装 Neo4j(2025最新·极简)

目录 1. 准备 2. 下载安装包 3. 一键安装 4. 启动 Neo4j 5.安装 Neo4j 的系统服务 Neo4j 是目前最流行的原生图数据库,用图结构(节点-关系-属性)存储数据,而非传统表结构。它专为海量关联数据设计,提供: * 原生图存储:基于免索引邻接结构,每个节点直接维护指向相邻节点的物理指针,实现 O(1) 时间复杂度的图遍历。 * Cypher 查询语言:ISO 标准化图查询语言,采用 ASCII-Art 模式匹配语法,支持可变长度路径、子图查询、聚合与更新混合事务。 * ACID 事务:支持完整事务、集群高可用,可承载企业级负载。 * 丰富生态:内置 Graph Data Science (GDS)

By Ne0inhk
Flutter 三方库 arcane_helper_utils 的鸿蒙化适配指南 - 实现具备通用逻辑增强与多维开发脚手架的实用工具集、支持端侧业务开发的效率倍增实战

Flutter 三方库 arcane_helper_utils 的鸿蒙化适配指南 - 实现具备通用逻辑增强与多维开发脚手架的实用工具集、支持端侧业务开发的效率倍增实战

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 arcane_helper_utils 的鸿蒙化适配指南 - 实现具备通用逻辑增强与多维开发脚手架的实用工具集、支持端侧业务开发的效率倍增实战 前言 在进行 Flutter for OpenHarmony 开发时,如何快速处理常见的字符串格式化、色值转换、日期计算或布尔值增强?虽然每一个功能都很小,但如果每个项目都重复造轮子,开发效率将大打折扣。arcane_helper_utils 是一款专注于极致实用的“瑞士军刀”型工具集。本文将探讨如何在鸿蒙端通过这类高内聚的 Utility 集实现极致、丝滑的业务交付。 一、原直观解析 / 概念介绍 1.1 基础原理 该库通过对 Dart 原生类型(Object, String, List, Map, Bool)

By Ne0inhk