Linux信号——信号的保存(2)
关于core和term两种终止方式
core是什么?
将进程在内存中的核心数据(与调试有关)转存到磁盘中形成core,core.pid的文件。
core dump:核心转储。
core与term的区别: term只是普通的终止,而core终止方式还要形成与调试相关的文件。
为什么要有core?
一个进程异常退出了,我们想知道为什么退出,通过core 可以定位到进程为什么退出,以及执行到哪行代码退出的。总的来说协助我们进行调试。
core的使用
如何打开Linux中的core功能?
开启Linux的 core dump 功能
ulimit [选项] [限制值]
ulimit -a 显示当前 Shell 的所有资源限制设置。
ulimit -c 10240 打开,控制core文件生成大小不超过10240kb。
ulimit -c 0 关闭,控制core文件生成大小不超过0kb,即无法生成core文件。
例:用 ulimit -a 进行查看资源限制。

上图 core file size 是0说明关闭了core dump
ulimit -c 10240进行开启。

关于core文件协助我们进行调试
在运行程序时出现异常,产生core文件后。
gdb 文件名(进入调试模式)
core-file core 直接定位到出错代码
云服务器默认将进程core退出,进行了特定的设定,默认core是被关闭的。
为什么默认关闭核心转储功能?防止未知的core dump一直进行,产生core文件,导致服务器磁盘被打满。
信号的保存
实际执行信号的处理动作称之为信号的递达。有三种方式1.默认 2.忽略 3.自定义
信号从产生到递达之间的状态,称为信号的未决(pending)。
进程可以选择阻塞(block)某个信号。

如果一个信号被阻塞(屏蔽),则该信号永远不会被递达处理,除非解除阻塞。
阻塞vs忽略 区别:忽略是一种信号的递达方式,阻塞是不让指定信号递达(忽略是已读不回,阻塞是根本收不到)。
操作系统发送信号,实际上就是操作系统在目标进程中写入信号,如何写入?就是在两个位图和一个函数指针数组中写入!如下图。

进程的PCB结构体中有两个uint32_t的变量——block和pending,它们有32个bit位,修改相应的bit位就能记录该信号是否传入,handler是一个函数指针数组,里面存储的是信号执行的方法
关于三张位图匹配的操作
信号集数据类型——sigset_t
sigset_t 是 POSIX 标准中定义的一个数据类型(类似于int double float),用于表示信号集(signal set)。它本质上是一个位图结构,其中每一位对应一个特定的信号。
//定义数据类型
//仅是定义到栈上
sigset_t s;//没有将数据设置进内核中!
信号集基本操作函数
int sigemptyset(sigset_t *set); // 初始化空信号集(不包含任何信号)
int sigfillset(sigset_t *set); // 初始化包含所有信号的信号集
int sigaddset(sigset_t *set, int signum); // 添加信号到信号集
int sigdelset(sigset_t *set, int signum); // 从信号集中删除信号
int sigismember(const sigset_t *set, int signum); // 检查信号是否在信号集中
注意:sigset_t 是不透明类型,必须使用标准函数操作,不能直接访问其内部。
例子:
//仅仅是定义到栈上,没有将数据结果设置进内核中
sigset_t s;
sigemptyset(&s);//初始化空信号集(不包含任何信号)
sidaddset(&s,2);// 添加2号信号到信号集
sigprocmask——操作block表
调用函数sigpromask可以读取或更改信号屏蔽字(阻塞信号集),简而言之,该函数可以检查和修改block位图。
#include <signal.h>int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
参数说明
how: 指定如何修改信号掩码,可取以下值:
| 关键字 | 作用 |
|---|---|
| SIG_BLOCK | 将 set 中的信号添加到当前阻塞信号集中(阻塞这些信号)相当于mask = mask| set |
| SIG_UNBLOCK | 从当前阻塞信号集中移除 set 中的信号(解除阻塞这些信号)相当于mask = mask &~ set |
| SIG_SETMASK | 直接将当前阻塞信号集设置为 set(完全替换)相当于mask = set |
set: 指向信号集的指针,包含要修改的信号。如果为 NULL,则 how 参数被忽略,函数仅获取当前信号掩码到 oldset。
oldset: 输出型参数,它的作用是用来保存调用前的信号屏蔽字。(oldset保存的是set设置前的那一次信号屏蔽字。)
返回值
成功时返回 0,失败时返回 -1 并设置 errno。
例子:
#include <signal.h>
#include <stdio.h>
#include <unistd.h>int main() {sigset_t new_set, old_set;// 初始化一个空的信号集sigemptyset(&new_set);// 添加 SIGINT 到信号集sigaddset(&new_set, SIGINT);// 阻塞 SIGINT 信号if (sigprocmask(SIG_BLOCK, &new_set, &old_set) == -1) {perror("sigprocmask");return 1;}printf("SIGINT is now blocked. Try Ctrl+C...\n");sleep(5); // 在这5秒内Ctrl+C不会终止程序// 恢复原来的信号掩码if (sigprocmask(SIG_SETMASK, &old_set, NULL) == -1) {perror("sigprocmask");return 1;}printf("SIGINT is unblocked. Try Ctrl+C again...\n");sleep(5);return 0;
}
sigpending——操作pending表
#include <signal.h>int sigpending(sigset_t *set);
参数说明
set:输出型参数,指向 sigset_t 类型的指针,用于接收pending 信号集。
返回值
成功:返回 0。
失败:返回 -1,并设置 errno 。
signal——操作handler表
#include <signal.h>void (*signal(int signum, void (*handler)(int)))(int);
参数说明
signum: 要处理的信号编号(如 SIGINT、SIGTERM 等)
handler: 信号处理函数,可以是:
| 关键字 | 作用 |
|---|---|
| SIG_IGN | 忽略该信号 |
| SIG_DFL | 恢复默认行为 |
| 自定义函数 | 用户定义的信号处理函数 |
一个场景
- 屏蔽2号信号。
- 获取进程的pending位图,打印所有的pending位图,循环往复。
- 未来我们给目标发送2号信号——2号信号不会被递达,一直在pending位图中。
- 获取进程的pending位图,打印所有的pending位图,循环往复。
- 解除屏蔽2号信号——2号信号最终被递达。
- 获取进程的pending位图,打印所有的pending位图,循环往复。
例子:屏蔽二号信号
#include<iostream>
#include<signal.h>
#include<unistd.h>
#include<sys/wait.h>void PrintSig(sigset_t &pending)
{std::cout << "Pending bitmap:";for(int signo = 31;signo>0;signo--){if(sigismember(&pending,signo)){std::cout << "1";}else{std::cout << "0";}}std::cout << std::endl;
}
int main()
{//1.屏蔽2号信号sigset_t block,oblock;sigemptyset(&block);sigemptyset(&oblock); sigaddset(&block, 2);//目前所有的修改,根本没有设置进当前进程的PCB中的block位图中//1.1开始屏蔽2号信号,其实就是设置进内核中int n = sigprocmask(SIG_SETMASK, &block, &oblock);//oblock保存的是block设置前的那一次信号屏蔽字。while(true){//2.获取进程的pending位图sigset_t pending;sigemptyset(&pending);n = sigpending(&pending);//3.打印pending位图中收到的信号PrintSig(pending);sleep(1);}std::cout << "block 2 signal success"<< std::endl;return 0;
}
结果:按下ctrl+C后,信号写入pending中,但是block位图中2号信号设置屏蔽,导致程序不终止。

如果能将所有信号屏蔽呢?是否进程将不会被杀死?
结论:9,19号信号不允许被屏蔽,18号信号会被特殊处理。
例子:解除屏蔽2号信号
#include<iostream>
#include<signal.h>
#include<unistd.h>
#include<sys/wait.h>
void handler(int signo)
{std::cout << signo << "信号被递达处理..." << std::endl;
}
void PrintSig(sigset_t &pending)
{std::cout << "Pending bitmap:";for(int signo = 31;signo>0;signo--){if(sigismember(&pending,signo)){std::cout << "1";}else{std::cout << "0";}}std::cout << std::endl;
}
int main()
{//对2号信号进行自定义捕捉——不让进程因为2号信号而终止signal(2,handler);//1.屏蔽2号信号sigset_t block,oblock;sigemptyset(&block);sigemptyset(&oblock); sigaddset(&block, 2);//目前所有的修改,根本没有设置进当前进程的PCB中的block位图中//1.1开始屏蔽2号信号,其实就是设置进内核中int n = sigprocmask(SIG_SETMASK, &block, &oblock);//oblock保存的是block设置前的那一次信号屏蔽字。int cnt = 0;while(true){//2.获取进程的pending位图sigset_t pending;sigemptyset(&pending);n = sigpending(&pending);//3.打印pending位图中收到的信号PrintSig(pending);if(sigismember(&pending,2)){cnt++; }//4.解除对2号信号的屏蔽if(cnt == 5){std::cout<<"解除对2号信号的屏蔽"<<std::endl;n = sigprocmask(SIG_UNBLOCK,&block,&oblock);//2号信号会被递达,默认处理是终止进程cnt++;}sleep(1);}std::cout << "block 2 signal success"<< std::endl;return 0;
}
结果:在一段时间后Ctrl+c,发送二号信号,首先存储进pending位图中,5秒钟后解除对2号信号的屏蔽,这时2号信号被递达处理,之后pending位图中2号信号位被清空。

细节:
- 递达信号的时候,就一定会把对应的pending位图清0.
- 先清0,再递达,还是先递达,再清0?
答案是先清0,再递达。
验证:
void handler(int signo)
{sigset_t pending;sigemptyset(&pending);int n = sigpending(&pending);//正在处理2号信号std::cout << "递达中...";PrintSig(pending);// 是0:递达之前,pending 2号已经被清0. 是1:pending 2号被清0一定是递达后 std::cout << signo << "信号被递达处理..." << std::endl;
}
结果:

相关文章:
Linux信号——信号的保存(2)
关于core和term两种终止方式 core是什么? 将进程在内存中的核心数据(与调试有关)转存到磁盘中形成core,core.pid的文件。 core dump:核心转储。 core与term的区别: term只是普通的终止,而core终止方式还要…...
PyQt6实例_A股日数据维护工具_权息数据增量更新线程
目录 前置: 代码: 1 工作类 2 数据库交互 3 主界面启用子线程 视频: 前置: 1 本系列将以 “PyQt6实例_A股日数据维护工具” 开头放置在“PyQt6实例”专栏 专栏地址 https://blog.csdn.net/m0_37967652/category_12929760.h…...
【蓝桥杯嵌入式——学习笔记一】2016年第七届省赛真题重难点解析记录,闭坑指南(文末附完整代码)
在读题过程中发现本次使用的是串口2,需要配置串口2。 但在查看产品手册时发现PA14同时也是SWCLK。 所以在使用串口2时需要拔下跳线帽去连接CH340。 可能是用到串口2的缘故,在烧录时发现报了一个错误。这时我们要想烧录得按着复位键去点击烧录,…...
基础常问 (概念、代码)
读源码 代码题 Void方法 ,也可以提前rerun;结束 RandomAccessFile类(随机访问文件) 在 Java 中,可以使用RandomAccessFile类来实现文件指针操作。RandomAccessFile提供了对文件内容的随机访问功能,它的文件指针可以通…...
大学生机器人比赛实战(一)综述篇
大学生机器人比赛实战 参加机器人比赛是大学生提升工程实践能力的绝佳机会。本指南将全面介绍如何从零开始准备华北五省机器人大赛、ROBOCAN、RoboMaster等主流机器人赛事,涵盖硬件设计、软件开发、算法实现和团队协作等关键知识。 一、比赛选择与准备策略 1.1 主…...
什么是宽带拨号?
宽带拨号(PPPoE拨号)是一种通过账号密码认证接入互联网的方式,常见于家庭宽带、企业专线等场景。用户需要通过路由器或电脑进行拨号连接,运营商验证身份后分配IP地址,才能正常上网。 1. 宽带拨号的工作原理 PPPoE协议&…...
J1 ResNet-50算法实战与解析
🍨 本文為🔗365天深度學習訓練營 中的學習紀錄博客🍖 原作者:K同学啊 | 接輔導、項目定制 一、理论知识储备 1. 残差网络的由来 ResNet主要解决了CNN在深度加深时的退化问题(梯度消失与梯度爆炸)。 虽然B…...
[MySQL初阶]MySQL(8)索引机制:下
标题:[MySQL初阶]MySQL(8)索引机制:下 水墨不写bug 文章目录 四、从问题到底层,从现象到本质1.为什么插入的数据默认排好序2.MySQL的Page(1)为什么选择用Page?(2&#x…...
Muduo网络库实现 [九] - EventLoopThread模块
目录 设计思路 类的设计 模块的实现 私有接口 公有接口 设计思路 我们说过一个EventLoop要绑定一个线程,未来该EventLoop所管理的所有的连接的操作都需要在这个EventLoop绑定的线程中进行,所以我们该如何实现将EventLoop和线程绑定呢?…...
Vim操作指令全解析
Vim是我们在Linux日常工作中不可或缺的文本编辑器。它强大的功能和高效的编辑方式可以极大提升工作效率。本文将全面解析Vim的各种操作指令,从基础操作到高级技巧。 一、Vim模式解析 Vim是一个模式化编辑器,理解不同模式是掌握Vim的关键: …...
《K230 从熟悉到...》识别机器码(AprilTag)
《K230 从熟悉到...》识别机器码(aprirltag) tag id 《庐山派 K230 从熟悉到...》 识别机器码(AprilTag) AprilTag是一种基于二维码的视觉标记系统,最早是由麻省理工学院(MIT)在2008年开发的。A…...
VMware ESXi:企业级虚拟化平台详解
VMware ESXi:企业级虚拟化平台详解 目录 什么是VMware ESXi? ESXi的发展历史 ESXi的核心特性 3.1 裸机架构(Type-1 Hypervisor) 3.2 轻量化与高性能 3.3 集中管理(vCenter集成) ESXi的架构与工作原理…...
使用 PyTorch 的 `optim.lr_scheduler.CosineAnnealingLR` 学习率调度器
使用 PyTorch 的 optim.lr_scheduler.CosineAnnealingLR 学习率调度器 在深度学习中,学习率(Learning Rate, LR)是影响模型训练效果的一个关键超参数。一个合适的学习率调度策略可以帮助模型更快地收敛,同时避免陷入局部最优或振荡。PyTorch 提供了多种学习率调度器,其中…...
栈和队列的概念
1.栈的概念 只允许在固定的一端进行插入和删除,进行数据的插入和数据的删除操作的一端数栈顶,另一端称为栈底。 栈中数据元素遵循后进先出LIFO (Last In First Out) 压栈:栈的插入。 出栈:栈的删除。出入数据在栈顶。 那么下面…...
常用的元素操作API
click 触发当前元素的点击事件 clear() 清空内容 sendKeys(...) 往文本框一类元素中写入内容 getTagName() 获取元素的的标签名 getAttribute(属性名) 根据属性名获取元素属性值 getText() 获取当前元素的文本值 isDisplayed() 查看元素是否显示 get(String url) 访…...
红日靶场一实操笔记
一,网络拓扑图 二,信息搜集 1.kali机地址:192.168.50.129 2.探测靶机 注:需要win7开启c盘里面的phpstudy的服务。 nmap -sV -Pn 192.168.50.128 或者扫 nmap -PO 192.168.50.0/24 可以看出来win7(ip为192.168.50.128)的靶机开…...
SpringBoot集成Redis 灵活使用 TypedTuple 和 DefaultTypedTuple 实现 Redis ZSet 的复杂操作
以下是 Spring Boot 集成 Redis 中 TypedTuple 和 DefaultTypedTuple 的详细使用说明,包含代码示例和场景说明: 1. 什么是 TypedTuple 和 DefaultTypedTuple? TypedTuple<T> 接口: 定义了 Redis 中有序集合(ZSet…...
7-4 BCD解密
BCD数是用一个字节来表达两位十进制的数,每四个比特表示一位。所以如果一个BCD数的十六进制是0x12,它表达的就是十进制的12。但是小明没学过BCD,把所有的BCD数都当作二进制数转换成十进制输出了。于是BCD的0x12被输出成了十进制的18了&#x…...
Golang改进后的任务调度系统分析
以下是整合了所有改进点的完整代码实现: package mainimport ("bytes""context""fmt""io""log""net/http""sync""time""github.com/go-redis/redis/v8""github.com/robfig/…...
【目标检测】【深度学习】【Pytorch版本】YOLOV2模型算法详解
【目标检测】【深度学习】【Pytorch版本】YOLOV2模型算法详解 文章目录 【目标检测】【深度学习】【Pytorch版本】YOLOV2模型算法详解前言YOLOV2的模型结构YOLOV2模型的基本执行流程YOLOV2模型的网络参数YOLOV2模型的训练方式 YOLOV2的核心思想前向传播阶段反向传播阶段 总结 前…...
NineData云原生智能数据管理平台新功能发布|2025年3月版
本月发布 15 项更新,其中重点发布 3 项、功能优化 11 项、性能优化 1 项。 重点发布 基础服务 - MFA 多因子认证 新增 MFA 多因子认证,提升账号安全性。系统管理员开启后,所有组织成员需绑定认证器,登录时需输入动态验证码。 数…...
破局与赋能:信息系统战略规划方法论
信息系统战略规划是将组织的战略目标和发展规划转化为信息系统的战略目标和发展规划的过程,常见的方法有以下几种: 一、企业系统规划法(BSP) 1.基本概念:通过全面调查,分析企业信息需求,确定信…...
GLSL(OpenGL 着色器语言)基础语法
GLSL(OpenGL 着色器语言)基础语法 GLSL(OpenGL Shading Language)是 OpenGL 计算着色器的语言,语法类似于 C 语言,但提供了针对 GPU 的特殊功能,如向量运算和矩阵运算。 着色器的开头总是要声明…...
Redis基础知识-3
RedisTemplate对多种数据结构的操作 1. String类型 示例代码: // 保存数据 redisTemplate.opsForValue().set("user:1001", "John Doe"); // 设置键值对,无过期时间 redisTemplate.opsForValue().set("user:1002", &qu…...
Git Rebase 操作中丢失提交的恢复方法
背景介绍 在团队协作中,使用 Git 进行版本控制是常见实践。然而,有时在执行 git rebase 或者其他操作后,我们可能会发现自己的提交记录"消失"了,这往往让开发者感到恐慌。本文将介绍几种在 rebase 后恢复丢失提交的方法。 问题描述 当我们执行以下操作时,可能…...
【diffusers 进阶(十五)】dataset 工具,Parquet和Arrow 数据文件格式,load dataset 方法
系列文章目录 【diffusers 极速入门(一)】pipeline 实际调用的是什么? call 方法!【diffusers 极速入门(二)】如何得到扩散去噪的中间结果?Pipeline callbacks 管道回调函数【diffusers极速入门࿰…...
unity各个面板说明
游戏开发,unity各个面板说明 提示:帮帮志会陆续更新非常多的IT技术知识,希望分享的内容对您有用。本章分享的是Python基础语法。前后每一小节的内容是存在的有:学习and理解的关联性,希望对您有用~ unity简介-unity基础…...
游戏引擎学习第199天
回顾并发现我们可能破坏了某些东西 目前,我们的调试 UI 运行得相对顺利,可以创建可修改的调试变量,也可以插入分析器(profiler)等特殊视图组件,并进行一些交互操作。然而,在上一次结束时&#…...
Linux红帽:RHCSA认证知识讲解(十)使用 tar创建归档和压缩文件
Linux红帽:RHCSA认证知识讲解(十)使用 tar创建归档和压缩文件 前言一、归档与压缩的基本概念1.1 归档与压缩的区别 二、使用tar创建归档文件2.1 tar命令格式2.2 示例操作 三、使用tar进行压缩3.2 命令格式3.3 示例操作 前言 在红帽 Linux 系…...
端到端机器学习流水线(MLflow跟踪实验)
目录 端到端机器学习流水线(MLflow跟踪实验)1. 引言2. 项目背景与意义2.1 端到端机器学习流水线的重要性2.2 MLflow的作用2.3 工业级数据处理需求3. 数据集生成与介绍3.1 数据集构成3.2 数据生成方法4. 机器学习流水线与MLflow跟踪4.1 端到端机器学习流水线4.2 MLflow跟踪实验…...
