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

Linux---进程信号

一、预备

1.信号

①物理:闹钟,红绿灯,上课铃声,狼烟,电话铃声,敲门声......

②什么叫信号:终端人正在做的事情,是一种事件的异步通知机制

③技术层面:信号是一种给进程发送的,用来进行事件异步通知的机制

④异步:两件事情同步进行互不干扰,信号的产生,先对于进程的运行,是异步的!

2.基本结论

①信号处理,进程在信号没有产生的时候,早就直到信号该如何处理了

②信号的处理,不是立即处理,二十可以等一会再处理,合适的时候,进行信号的处理

③人能识别信号,是被提前“教育”过的,进程也是如此,OS程序员设计的进程,进程早已内置了对于信号的识别和处理方式!

④信号源非常多->给进程产生信号的信号源也非常多。

二、信号的产生

1.键盘产生信号

①信号有哪些

其中1~31是普通信号,34~64是实时信号,无需我们考虑

②ctrl+c:向目标进程发送二号信号(SIGINT)

Ⅰ代码演示

Ⅱ ctrl+c是给目标进程发送信号,相当一部分信号的处理动作,就是让自己终止

③信号的三种操作:进程收到信号之后,合适的时候,处理信号的动作有三种

Ⅰ默认处理动作(大部分信号默认处理动作是终止)

Ⅱ自定义处理动作

Ⅲ忽略处理

⑤前台进程和后台进程

Ⅰ前台进程(./test):键盘产生的进程,只能发给前台进程

当运行程序时,输入ls,pwd等指令没有结果,因为前台进程只能有一个,系统运行./test就不能运行bash进程了

Ⅱ后台进程(./test &):ctrl+c无法相应

运行程序时,bash为前台进程,所以输入命令时可以执行

Ⅲ区别与共性

前台进程能从键盘上获取标准输入,后台进程无法从标准输入中获取内容;但是都可以向标准输出上打印

Ⅳ原因

键盘只有一个,输入数据一定是给确定的进程的,前台进程必须只有一个,后台进程可以有多个,

前台的本质就是要从键盘获取数据的

Ⅴ相互转变

jobs:查询后台任务号

fg+任务号:后台变前台

ctrl+z:暂停前台任务,自动变后台

bg+任务号:暂停后运行后台任务

⑥什么叫做给进程发送信号

信号产生后,并不是立即处理,所以要求进程必须把信号记录下来,在合适的时候处理!

再task_struct中使用位图结构:收到几号信号将那位置1

发送信号本质就是向目标进程写信号(修改位图,pid和信号编号)

2.系统调用

①相关接口

Ⅰsignal:修改信号操作

Ⅱ kill: 杀死目标进程中的信号

Ⅲ raise:指明发送给信号

Ⅳ abort:使当前进程接收到信号而异常终止,使用6号信号,要求进程必须处理,忽视信号捕捉

②演示

sigal

mykill

二者同时运行

③9号和19号信号无法被捕捉

3.异常产生信号

①示例

Ⅰ除0

8号SIGFPE:浮点数错误

Ⅱ野指针

11号SIGSEGV:段错误

②本质使硬件无法产生页表无法对应从而返回错误

4.软件条件(SIGPIPE)

①alarm:闹钟,时间到向OS发送信号,默认终止

alarm(0):取消闹钟

14号信号SIGALRM

②代码演示

操作系统的执行方法,while循环从开机开始就不停

#include <functional>
#include <iostream>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#include <vector>void func1() {std::cout << "方法一" << std::endl;
}
void func2() {std::cout << "方法二" << std::endl;
}
void func3() {std::cout << "方法三" << std::endl;
}using func_t = std::function<void()>;
std::vector<func_t> funcs;void handlerSig(int sig) {std::cout << "###############" << std::endl;for (auto f : funcs)f();std::cout << "###############" << std::endl;int n = alarm(1);
}
int main() {funcs.push_back(func1);funcs.push_back(func2);funcs.push_back(func3);signal(SIGALRM,handlerSig);alarm(2);while (true) {pause();//暂停}
}

三、信号的保存

1.预备

实际执⾏信号的处理动作称为信号递达(Delivery)

②信号从产⽣到递达之间的状态,称为信号未决(Pending)。

③进程可以选择阻塞 (Block )某个信号。
④被阻塞的信号产⽣时将保持在未决状态,直到进程解除对此信号的阻塞,才执⾏递达的动作.
⑤注意,阻塞和忽略是不同的,只要信号被阻塞就不会递达,⽽忽略是在递达之后可选的⼀种处理动
作。

2.理解

在一个进程pcb中有三张表

①pending表(未决表):保存收到的信号的位图,bit位的位置表示第几个信号,内容(0或1)表示是否收到

②block表:bit位的位置表示第几个信号,bit的内容表示是否阻塞

③handler表:是一个函数指针数组,下标表示信号,当使用signal函数时,第二个参数就是传入这个表,有默认,自定义,忽略三种方式,使用signal就是自定义

3.sigprocmask

调用函数可以读取或者更改进程的信号屏蔽字

①how

how 是核心控制参数,用于指定 sigprocmask 如何修改当前进程的信号掩码,必须传入以下 3 个预定义常量之一,决定了 set 中信号集的使用逻辑:

②set

set 是一个指向 sigset_t 类型的指针,sigset_t 是系统定义的信号集数据结构(可理解为 “存储多个信号的容器”),用于指定要 “阻塞 / 解除阻塞 / 替换” 的具体信号。

关键说明:

  • set 的值取决于 how 的作用:

    • 当 how 为 SIG_BLOCK/SIG_UNBLOCK 时,set 需包含要 “添加阻塞” 或 “解除阻塞” 的信号;
    • 当 how 为 SIG_SETMASK 时,set 就是新的完整信号掩码;
    • 若 set 为 NULL,表示 “不修改信号集”,仅通过 oldset 获取当前掩码(此时 how 参数会被忽略)。

③oldset(输出型参数)

oldset 是一个指向 sigset_t 类型的指针,用于保存修改前的 “旧信号掩码”(即调用 sigprocmask 前进程的信号掩码状态)。

关键说明:

  • 若 oldset 不为 NULL:系统会将修改前的信号掩码写入 oldset 指向的内存,便于后续恢复原状态(例如临时阻塞信号后,需还原为原来的阻塞规则);
  • 若 oldset 为 NULL:表示 “不需要保存旧掩码”,仅执行修改操作。

4.sigpending

①功能

1. 核心概念:待处理信号(Pending Signal)

在理解 sigpending 前,需先明确 “待处理信号” 的定义:

  • 当一个信号被发送给进程时,系统会先检查该信号是否在进程的信号掩码中(即是否被阻塞);

  • 未被阻塞:进程会立即处理该信号(执行信号处理函数或默认行为);

  • 已被阻塞:信号不会被立即处理,而是被标记为 “待处理” 状态,暂存于进程的 “待处理信号队列” 中;

  • 当该信号从信号掩码中被解除阻塞(如通过 sigprocmask(SIG_UNBLOCK))后,进程会立即处理这个待处理信号。

注意:每个信号类型(如 SIGINT、SIGQUIT)在待处理队列中最多只有一个实例—— 若同一信号被多次发送且均被阻塞,只会记录一次,解除阻塞后也仅处理一次。

②参数:sigset_t *set(输出型参数)

set 是一个指向 sigset_t 类型(信号集)的指针,其作用是接收进程当前所有待处理信号的集合

5.sig集合

①sigemptyset

  • 功能:初始化一个信号集,将该信号集中所有信号的对应标志位都设置为 0,即清空信号集,使其不包含任何信号。
  • 返回值:成功时返回 0;若出现错误,返回 - 1。

②sigfillset

  • 功能:将信号集中的所有信号对应的标志位都设置为 1,也就是使该信号集包含系统支持的所有信号。
  • 返回值:成功时返回 0;若出现错误,返回 - 1。

③sigaddset

  • 功能:向指定的信号集 set 中添加一个特定的信号。signum 参数表示要添加的信号编号,比如常见的 SIGINT(信号编号通常为 2,代表终端中断信号)、SIGTERM(终止信号)等。
  • 返回值:成功时返回 0;若出现错误(例如 signum 不是一个有效的信号编号,或者 set 指针无效等情况),返回 - 1。

④sigdelset

  • 功能:从指定的信号集 set 中删除一个特定的信号。signum 是要删除的信号编号。
  • 返回值:成功时返回 0;若出现错误(比如 signum 不是一个有效的信号编号,或者 set 指针无效,又或者要删除的信号原本就不在信号集中 ),返回 - 1。

⑤sigismember

  • 功能:检查指定的信号 signum 是否存在于信号集 set 中。这是一个查询函数,用于判断某个信号是否被包含在特定的信号集中。
  • 返回值:如果信号 signum 在信号集 set 中,返回 1;如果信号 signum 不在信号集 set 中,返回 0 ;若出现错误(比如 set 指针无效),返回 - 1。

⑥代码使用

#include <iostream>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>void PrintPending(sigset_t &pending) {printf("我是一个进程(%d), pending: ", getpid());for (int signo = 31; signo > 0; signo--) {if (sigismember(&pending, signo)) {std::cout << "1";} else {std::cout << "0";}}std::cout << std::endl;
}// 先将2号信号进行屏蔽,然后不断获取pending表,然后向目标进程发送信号int main() {// 1.屏蔽二号信号sigset_t block, oblock;sigemptyset(&block);sigemptyset(&oblock); // 清空sigaddset(&block, SIGINT); // 添加信号sigprocmask(SIG_SETMASK, &block, &oblock);int cnt = 0;while (true) {// 获取pending集合sigset_t pending;sigpending(&pending);PrintPending(pending);sleep(1);cnt++;}return 0;
}

6.核心转储

Action中有些时Trem有些时Core,他们都是终止信号,但是有差异

  • Term:单纯的终止进程,没有多余的动作
  • Core:先进性核心转储,再终止进程

核心转储及其作用
核心转储(core dump)是指在程序发生严重错误导致异常终止时,操作系统将程序的内存内容以及相关的调试信息保存到一个特殊的文件中,以供后续分析和调试使用。这个文件通常被称为核心转储文件或核心文件。

核心转储文件包含了程序崩溃时内存的快照,以及与进程相关的其他信息,如寄存器状态、调用栈、变量值等。这对于开发人员来说是非常有价值的,因为它提供了关于程序崩溃原因的详细信息,有助于识别和调试问题。

核心转储文件通常以 “core” 或者在某些系统中以进程ID为文件名的形式保存在程序当前工作目录或系统指定的核心转储文件目录中。它们对于排查由于程序错误、内存损坏或其他异常情况引起的问题非常有用。

有一些关键的概念和注意事项与核心转储相关:

ulimit 设置: 操作系统可能会设置 ulimit(用户资源限制)来限制核心转储文件的大小,以避免占用过多磁盘空间。

调试符号: 为了更好地解析核心转储文件,通常需要保留程序的调试符号。调试符号是编译时信息,包含了程序源代码的映射关系,有助于将内存地址映射回源代码。

调试工具: 使用调试工具(如gdb)可以加载核心转储文件,并允许开发人员分析崩溃时的状态、查看堆栈跟踪,以及检查变量值等。

产生核心转储: 在Unix-like系统中,可以通过在程序中调用 ulimit 设置允许生成核心转储文件,或者在终端运行程序时使用 ulimit -c unlimited 临时修改。

再见

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

相关文章:

  • 从汽车传动到航空航天:滚珠花键的跨领域精密革命
  • 电子电气架构 --- 汽车座舱市场发展核心方向
  • leetcode 69.x的平方根
  • 网站建设策划方案书论文免费seo诊断
  • 【密码学实战】openHiTLS keymgmt命令行:密钥管理工具
  • 网站上线倒计时html5模板企业培训机构有哪些
  • 中型规模生产架构部署详细步骤
  • 如何加强英文网站建设重庆网站建设的公司哪家好
  • 逆向分析文档:基于 app.endata.com.cn 票房数据接口的加密与解密流程
  • 为什么做腾讯网站如何压缩网站
  • 吴恩达机器学习课程(PyTorch适配)学习笔记:1.1 基础模型与数学原理
  • 【全志V821_FoxPi】6-1 MIPI协议与MIPI摄像头
  • 【防火墙源码】WordPress防火墙插件1.0测试版
  • 全国美容网站建设房源信息网
  • CentOS 7 环境下 MySQL 5.7 深度指南:从安装、配置到基础 SQL 操作
  • ⚡ arm 32位嵌入式 Linux 系统移植 NTP 服务
  • 抖音,小红书等自媒体平台多开账号如何操作不违规
  • [Java]PTA: jmu-Java-03面向对象基础-Object
  • 【大模型实战篇】基于xiaohongshu-mcp实现对话模式的小红书笔记操作
  • LangChain详解(一)
  • 门户网站建设需求wordpress云主机
  • 【OpenArm|Control】openarm机械臂ROS2仿真控制
  • 网站开发小组百度网页制作网站建设
  • 中小型项目组织架构和职能说明
  • wordpress发表文章更新失败网站标题优化工具
  • C++网络编程(五)socket编程---从socket()到connect()
  • 23-25年总结:23年因为大模型而转型科技,24年起发力具身,25年长沙具身开始一轮轮突飞猛进
  • AI智能体(Agent)大模型入门【7】--构建传统的RAG应用
  • 淮阴区建设局网站网站备案变更公司名称
  • Bittensor 中国巡回 Meetup|上海站