Linux 学习之路 - 信号的保存

news2024/9/21 20:32:23

前面已经介绍过信号的产生,本文将继续介绍信号的保存与处理。

1、上篇文章的遗留问题

从上篇文章(Linux学习之路 -- 信号概念 && 信号的产生-CSDN博客)中,其实还遗留了一些问题。OS在接受到信号后,大部分的进程的处理方式都是终止进程。但是终止进程的方式有Term和Code两种方式。那么两种进程退出的方式有何区别呢?

Term就表示正常的退出,而code退出会产生核心转储文件。在云服务器中,使用code退出时,默认是将code产生核心转储文件的功能关闭的。而我们如果想要查看该功能是否被打开。我们就可以使用"ulimit -a"选项,对该功能进行查看。

其中的第一项"core file size" 就表示code功能是否被打开。core file size其实也就是表示核心转储文件的大小,如果为零,也就表示没有。我们要恢复该功能,只要将其设置一定大小的正整数即可(单位为KB)。我们可以使用"ulimit -c + 指定大小的整数",如果不想该文件的大小收到限制,就把前面这条命令中的整数改为unlimited即可。

核心转储文件的作用:如果进程运行出现异常时,系统就会将进程在内存中的数据(主要与调试有关)转到磁盘中,形成core、core.pid文件。

该文件主要用于帮助我们进行调试,当我们使用gdb时,能够直接定位到对应出错的行号与文件。我们在打开gdb时,直接输入core-file + core(这里是核心转储的文件名,如果有后缀pid,记得加上)即可。

core dumped 表示形成核心转储文件,这个和前面我们讲述的进程退出时的知识有些许关联。


进程退出时,会返回一个整型。OS以后16个字节对进程的退出状态进行标识。中间其实缺少了一个比特没有介绍,这个比特位就是core dumped标志,用于标识是否形成核心转储文件。

但是核心转储文件虽然能帮我们定位程序出错的位置,但在实际的云服务器上,我们的服务是需要不断运行的。有时候恢复正常服务,需要很长的时间。在此期间,有可能OS会一直输出core文件,导致服务器磁盘被打满,这就会导致服务器也直接挂掉。所以,正常情况下,这个core dump功能是会被默认关闭的。

2、信号的保存

在正式介绍信号保存之前,我们需要把前面的概念修正一下。
<1>实际执行信号的处理动作称为信号递达。(默认、忽略、自定义)
<2>信号从产生到递达之间的状态称为信号未决。(存储信号)
<3>进程是可以阻塞信号的。

1、基本流程

前面我们提到,当OS向进程发送信号,实际上是在向进程写入信号。而进程可能在处理其他事务,所以会使用一个位图来对信号进行保存。在struct task_struct 中就是以一个无符号整型变量对信号进行保存。同理,信号可以被进程阻塞,这个阻塞也是需要先存储信号,而OS也是使用了位图的方式,对其进行保存。当进程接受到信号时,会先保存信号。然后,在需要执行信号的默认处理方式前,判断信号是否被阻塞,如果是,就不处理该信号;不是就执行默认方法。(如果该信号被一直阻塞,那就一直不执行)

除了上述的两张位图,还有一个数组与进程处理信号相关。

这个数组是一个函数指针数组,里面存储了一些对应信号的默认处理方法。当OS接收到信号时,先将信号写进pending位图中,然后判断是否被阻塞。如果没有被阻塞,就找到对应的handler方法,处理信号,该数组的下标就代表了对应的信号。这里可以联想到signal接口处理信号的方式,当我们设定位自定义处理信号时,将该信号在handler_t中对应的默认处理方法替换成自定义函数地址。

2、三张表对应的系统接口和相关操作

1、五个常用的信号集函数

在OS中,我们查看pending位图和block位图,是不会直接传整型的,而是将存储的结构封装成了一个结构体,所以我们在上述的五个接口中均可以看见sigset_t类型的参数。下面一一解释一下对应接口的作用。

<1>sigemptyset

该接口用于将位图初始化为零,一般我们需要自己定义一个sigset_t变量,把这个变量用于存储系统中对应位图信息。而这个变量定义时不初始化,所以可能会出现随机数现象,该接口就是用于将变量中的数据全部清零。

<2>sigfillset

该接口用于将所有定义的信号,设进set这个参数信号集中。

<3>sigaddset 

该接口用于将signum信号添加进set这个信号集。

<4>sigdelset

该接口用于将signum信号从set信号集中删除。

<5>sigismember

该接口用于判断信号signum是否在set这个信号集中。

前四个接口调用成功返回零,失败返回-1。最后一个接口成功返回true,失败返回false。

2、sigprocmask

该接口可以读取或更改系统中对应的信号屏蔽集(block位图).

第一个参数表示所要对信号屏蔽集做的动作,第二个参数表示新的信号屏蔽字,第三个参数表示原来的信号屏蔽集。

第一个参数一般常用的有三个选择:SIG_BLOCK 、SIG_UNBLOCK、SIG_SETMASK。第一个选项表示将set这个信号集中的屏蔽的信号添加进现有的信号屏蔽集中;第二个选项表示将set这个信号集中屏蔽的信号从原有的信号删除;第三个选项表示将set这个信号集直接替换当前的信号屏蔽集。

调用成功返回0,失败返回-1。

3、sigpending 

该接口用于读取系统中的pending信号集(pending位图)。成功返回0,失败返回-1。

4、示例:

我们以下面的场景为例,演示一下上述的相关的接口的使用方式。

场景:我们当前将2号信号阻塞,然后不断向当前进程发送2号信号,观察pending表是否一直都保存着2号信号。(pending表中一般就一个信号,当收到新的不同的信号时,原有的信号会被消除)

#include <iostream>
#include <unistd.h>
#include <signal.h>

void Print(sigset_t &pe)
{
    std::cout << "pending map: ";
    for (int i = 31; i >= 1; i--)
    {
        if (sigismember(&pe, i))
        {
            std::cout << "1";
        }
        else
        {
            std::cout << "0";
        }
    }
    std::cout << std::endl;
}
int main()
{
    sigset_t block, oblock;
    sigemptyset(&block);
    sigemptyset(&oblock);

    sigaddset(&block, 2);
    int n = sigprocmask(SIG_BLOCK, &block, &oblock);
    if (n == 0)
    {

        while (true)
        {
            sigset_t pending;
            sigemptyset(&pending);
            sigpending(&pending);
            sleep(1);
            Print(pending);
        }
    }
    return 0;
}

运行结果:

我们可以看见,当我们将2号信号阻塞时,pending中的2号信号一直没有被处理。需要说明的是,我们不能直接打印pending表,OS是以sigset_t的类型对信号进行存储,里面可能包含有别的数据,所以直接打印是错误的。在代码中,需要使用sigismember来判断信号是否存储。

上面的示例,我们屏蔽了2号信号,那我们能不能屏蔽1到31号信号呢?如果不能,那么哪些信号不会被屏蔽呢?下面通过代码对该问题进行验证。

#include <iostream>
#include <unistd.h>
#include <signal.h>

void Print(sigset_t &pe)
{
    std::cout << "pending map: ";
    for (int i = 31; i >= 1; i--)
    {
        if (sigismember(&pe, i))
        {
            std::cout << "1";
        }
        else
        {
            std::cout << "0";
        }
    }
    std::cout << std::endl;
}
int main()
{
    sigset_t block, oblock;
    sigemptyset(&block);
    sigemptyset(&oblock);
    for(int i = 1; i < 32; i++)
    {
        sigaddset(&block, i);
    }
    sigaddset(&block, 2);
    int n = sigprocmask(SIG_BLOCK, &block, &oblock);
    if (n == 0)
    {

        while (true)
        {
            sigset_t pending;
            sigemptyset(&pending);
            sigpending(&pending);
            sleep(1);
            Print(pending);
        }
    }
    return 0;
}

运行结果

运行至九号信号时,进程结束。说明九号进程不可被屏蔽。后面的信号就不做实验了,在这31个信号中,还有19号信号也不可被屏蔽,其中我们将18号信号屏蔽时,附近的几个信号会在信号屏蔽集中被剔除。这两个信号被禁止屏蔽其实也就是为了防止异常进程不断运行,影响OS的正常运转或阻止异常进程读取核心数据。

通过上述的接口,我们可以实现信号的屏蔽,也可以实现信号屏蔽的解除。这里就不做演示了,但需要注意的是,一旦信号的屏蔽被解除后,pending中的信号是先被清零,再被递达。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2103039.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

合宙低功耗4G模组Air780E——产品规格书

Air780E 是合宙通信推出的 LTE Cat.1 bis通信模块&#xff1b; 采用移芯EC618平台&#xff0c;支持 LTE 3GPP Rel.13 技术。 Air780E特点和优势总结如下&#xff1a; 全网通兼容性&#xff1a; 作为4G全网通模块&#xff0c;兼容不同运营商网络&#xff0c;包括但不限于移动、…

【C++ Primer Plus习题】10.1

问题: 解答: main.cpp #include <iostream> #include "BankAccount.h" using namespace std;int main() {BankAccount BA1("韩立","韩跑跑",1);BA1.get_info();BankAccount BA;BA.init_account("姚国林", "amdin", 1…

国际化产品经理的挑战与机遇:跨文化产品管理的探索

全球化背景下的产品管理变革 在当今全球化的背景下&#xff0c;科技的进步和通信技术的普及&#xff0c;使得世界变得更加紧密相连。产品不再仅仅局限于单一市场&#xff0c;而是面向全球用户&#xff0c;这对产品经理提出了新的挑战与机遇。跨文化的产品管理要求产品经理不仅…

09-03 周二 ansible部署和节点管理过程

09-03 周二 ansible部署和节点管理过程 时间版本修改人描述2024年9月3日10:08:58V0.1宋全恒新建文档&#xff0c; 简介 首先要找一个跳板机&#xff0c;来确保所有的机器都可以访问。然后我们围绕ansible来搭建环境&#xff0c;方便一键执行所有的命令&#xff0c;主要的任务是…

通信算法之232: 无线发射功率和信号强度,常用单位dB、dBm、dBi和dBd介绍

[转载] 无线功率和信号强度的基本概念 在无线网络中&#xff0c;使用AP设备和天线来实现有线和无线信号互相转换。如下图所示&#xff1a; 有线网络侧的数据从AP设备的有线接口进入AP后&#xff0c;经AP处理为射频信号&#xff0c;从AP的发送端&#xff08;TX&#xff09;经过…

JAVA-JVM 内存模型类加载器GC算法GC调优

JAVA-JVM 内存模型&类加载器&GC算法&GC调优 什么是JVM JVM 内存模型 JVM的GC算法 JVM类加载器 什么是JVM ? [[jvm]]是Java Virtual Machine&#xff08;Java虚拟机&#xff09;的缩写&#xff0c;JVM是一个虚构出来的计算机&#xff0c;有着自己完善的硬件架构&a…

Qwen-7B-Chat大模型安装训练推理-helloworld

初始大模型之helloworld编写 开发环境&#xff1a;modelscope GPU版本上测试的&#xff0c;GPU免费36小时 ps:可以不用conda直接用环境自带的python环境使用 魔搭社区 安装conda wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh 1.2 bash Mini…

港科夜闻 | 香港科大举办开学嘉年华,叶玉如校长勉励新生发掘潜能传承凡事皆可为精神...

关注并星标 每周阅读港科夜闻 建立新视野 开启新思维 1、香港科大举办开学嘉年华&#xff0c;叶玉如校长勉励新生发掘潜能传承「凡事皆可为」精神。迎接新学年&#xff0c;香港科大于9月2日起举行为期两天的开学嘉年华「Fire Up Your Year」&#xff0c;校长叶玉如教授联同一众…

AI写作保姆级方法论第六节-AI的终极调教心法(问题+解决方案)

效果是什么 大象基于大量的实战经验&#xff0c;总结出了AI prompt调教的终极杀手锏&#xff1a;【终极调教心法&#xff1a;1个原则和3个技巧】 一个原则&#xff0c;是指AI的【角色扮演法】&#xff0c;openai官方基于AI原理给出的让AI听话的技巧。所有AI的使用玩法&#xff…

Leetcode3250. 单调数组对的数目 I

Every day a Leetcode 题目来源&#xff1a;3250. 单调数组对的数目 I 解法1&#xff1a;记忆化搜索 题目输入一个数组nums。 假设有两个数组A和B&#xff0c;A递增&#xff0c;B递减&#xff0c;且 Ai Bi numsi ​ 问有多少对(A,B)数组对。 解法&#xff1a; 代码&…

java基础知识-JVM知识详解

一、JVM内存结构 Java虚拟机(JVM)的内存结构主要分为几个不同的区域,每个区域都有其特定的目的和功能。以下是JVM内存结构的主要组成部分: 先看一下总体的结构图 程序计数器(Program Counter Register) 这是一个较小的内存块,用于存储当前线程所执行的字节码指令的地址…

第T4周:猴痘病识别

本文为&#x1f517;365天深度学习训练营 中的学习记录博客原作者&#xff1a;K同学啊 我的环境&#xff1a; ● 语言环境&#xff1a;Python3.6.5 ● 编译器&#xff1a;jupyter notebook ● 深度学习框架&#xff1a;TensorFlow 2.6.2 ● 数据&#xff1a;猴痘病数据集 一、…

非 congda 环境 ubuntu 22.04 源码编译安装 pytorch 并初步检查可用性

非 congda 环境 编译安装 pytorch 0, 安装 cuda sdk &#xff0c;cudnn 及 nccl 按照官网步骤&#xff0c;blacklist需要特别注意 0.1 cuda sdk 0.2 cudnn 0.3 安装nccl git clone --recursive https://github.com/NVIDIA/nccl.git ls cd nccl/ make -j src.build sudo apt…

使用 docker 部署 kvm 图形化管理工具 WebVirtMgr

文章目录 [toc]前提条件镜像构建启动 webvirtmgr创建其他 superuser配置 nginx 反向代理和域名访问绑定 kvm 宿主机local sockettcp 连接 虚拟机创建创建快照虚拟机克隆删除虚拟机 kvm 官方提供了以下这些图形化管理&#xff0c;license 这块也提示了是商业版&#xff08;Comme…

rometheus Blackbox监控网站

Blackbox Exporter简介 blackbox_exporter 是 Prometheus 拿来对 http/https、tcp、icmp、dns、进行的黑盒监控工具&#xff0c;也就是从服务、主机等外部进行探测&#xff0c;来查看服务、主机等是否可用。 Blackbox Exporter 默认端口是 9115&#xff0c; 安装1 wget htt…

Codeforces Round (Div.3) C.Sort (前缀和的应用)

原题&#xff1a; time limit per test&#xff1a;5 seconds memory limit per test&#xff1a;256 megabytes You are given two strings a and b of length n. Then, you are (forced against your will) to answer q queries. For each query, you are given a range …

Dify 与 FastGPT 流程编排能力对比分析

Dify 与 FastGPT 流程编排能力对比分析 一、引言 在人工智能快速发展的今天&#xff0c;大语言模型&#xff08;LLM&#xff09;应用平台正在重塑各行各业的工作流程。其中&#xff0c;Dify 和 FastGPT 作为两款具有重要影响力的工具&#xff0c;凭借各自独特的流程编排能力&a…

智能化升级:AI在客服知识库中的应用

引言 在数字化时代&#xff0c;客户服务已成为企业竞争的关键一环。随着人工智能&#xff08;AI&#xff09;技术的飞速发展&#xff0c;传统客服模式正经历着前所未有的变革。AI与客服知识库的深度融合&#xff0c;不仅极大地提升了客服处理的效率与准确性&#xff0c;还为用…

unreal engine 5.4.4 runtime 使用PCG

Unreal PCG Runtime runtime环境下控制PCG PCG Graph 这里简单的在landscape上Spawn Static Mesh 和 Spawn Actor GraphSetting 自定义的参数&#xff0c;方便修改 场景 这里新建了一个蓝图Actor PCG_Ctrl, 用来runtime的时候控制PCG生成 Construct 获取场景中的PCGVolum…

Oracle版本简介手册

Oracle版本简介手册 图1—数据库发布路线图表 Oracle数据库的各个版本反映了其技术的发展历程和功能增强&#xff0c;从最早的Oracle 1&#xff08;1979年&#xff09;到最新的版本&#xff0c;每个版本都带来了新的特性和改进&#xff0c;以满足不断变化的企业需求。以下是Or…