【Linux】信号的产生

目录

    • 一. 信号的概念
      • signal() 函数
    • 二. 信号的产生
      • 1. 键盘发送
      • 2. 系统调用
        • kill()
        • raise()
        • abort()
      • 3. 软件条件
        • alarm()
      • 4. 硬件异常
        • 除零错误:
        • 野指针:
    • 三. 核心转储

一. 信号的概念

  • 信号是消息的载体, 标志着不同的行为; 是进程间发送异步信息的一种方式, 属于软中断.

  • 信号随时都可能产生, 是异步发送的, 所以进程并不会立即处理信号, 进程会在合适的时间进行统一处理; 所以进程必须有保存信号的能力;

  • 信号是以位图的形式保存在 task_struct 的 pending 中, 当进程接受到信号时, 进程会将信号对应的位置设置为 1 即可;

struct task_struct {
	//...
	struct signal_struct *signal;	// 指向进程信号描述符
    struct sighand_struct *sighand;	// 指向进程信号处理程序描述符
    sigset_t blocked;  				// 进程阻塞的信号, 信号按照比特位相对应
    struct sigpending pending;		// 进程的待处理信号
    //...
};
  • 信号的处理方式分为三种:
    默认动作
    自定义动作;
    忽略.

在 Linux 中可以使用指令查看信号列表

kill -l

在这里插入图片描述
一共 62 个信号, 其中 1~31 号信号为普通信号, 适用于基于时间片的分时操作系统; 34~64 号信号为实时信号, 适用于实时操作系统.

使用指令可以查看普通信号的说明

man 7 signal

在这里插入图片描述

signal() 函数

在这里插入图片描述

  • signal() 函数, 可以将 signum 指定信号的处理动作, 设置为 handler 动作; 但 SIGKILL 和 SIGSTOP 不能被捕捉或忽略.
#include <signal.h>

typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler);

参数:

  • signum: 信号编号, 设置的信号;
  • handler: 函数指针, 是信号的处理动作;
    若 handler 设置为 SIG_IGN, 那么设置的信号将会被忽略;
    若设置为 SIG_DFL, 那么信号将会执行默认动作;
    若设置为 自定义函数, 那么处理信号时, 将会调用自定义函数

返回值:

  • 若成功, 返回 signal handler 的前一个值; 若失败, 返回 SIG_ERR, 并且设置 erron.
    在这里插入图片描述

二. 信号的产生

1. 键盘发送

当操作系统从键盘中读取 “ctrl” + “c” 类似的特定的组合键时, 会将其解释为某种信号, 发送给前台进程.

  • 例:
    一个死循环的前台进程可以被 “ctrl” + “c” 终止,
#include <iostream>
#include <signal.h>

using namespace std;

int main()
{

    cout << endl;
    while (1) ;
    
    return 0;
}

在这里插入图片描述

将 2 号信号注册自定义行动 验证

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

using namespace std;

void handler(int signal)
{
    cout << endl << getpid() << " " << signal << endl;
}

int main()
{
    signal(2, handler);

    while (1) ;

    return 0;
}

在这里插入图片描述

2. 系统调用

kill()

在这里插入图片描述

  • kill() 函数, 发送指定信号至指定进程.
#include <sys/types.h>
#include <signal.h>

int kill(pid_t pid, int sig);

参数:

  • pid: 指定的进程 pid;
  • sig: 指定的信号编号;

返回值:

  • 若成功, 返回 0; 若失败, 返回 -1, 并且设置 errno.
    在这里插入图片描述
raise()

在这里插入图片描述

  • raise() 函数, 发送指定信号至当前进程.
#include <signal.h>

int raise(int sig);

参数:

  • sig: 指定的信号编号;

返回值:

  • 若成功, 返回 0; 若失败, 返回 非0, 并且设置 errno.
    在这里插入图片描述
abort()

在这里插入图片描述

  • abort() 函数, 发送 SIGABRT 信号至当前进程, 该函数从不返回.
#include <stdlib.h>

void abort(void);

3. 软件条件

这种方式在管道就出现了:
管道读写时, 若读端关闭, 写端继续写入时, 那么操作系统将会发送 SIGPIPE 信号终止写端.

alarm()

在这里插入图片描述

  • alarm() 函数, 将会在指定时间后, 发送 SIGALRM 信号值当前进程.
#include <unistd.h>

unsigned int alarm(unsigned int seconds);

参数:

  • seconds: 指定时间, 单位为秒;

返回值:

  • 若前一次 alarm() 函数没有剩余的时间, 返回 0; 若前一次 alarm() 函数有剩余的时间, 返回剩余的时间.
    在这里插入图片描述

4. 硬件异常

硬件异常是指 硬件在检测到错误条件后, 通知内核, 再由内核发送相应信号至相关进程.

除零错误:

当 CPU 发生除零错误后, CPU 会将内部的标志寄存器设置为 1, 表示出现数据异常; 之后通知操作系统, 由操作系统向进程发送 SIGFPE 信号, 该信号默认动作为终止程序;
但若将 SIGFPE 信号设置自定义动作或忽略, 未处理异常时, 该硬件的异常数据属于进程的上下文; 由于进程依旧运行, 并且状态寄存器依旧为异常状态, 那么操作系统会轮询式的发送异常信号至进程, 直至异常被处理或终止.

#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>

using namespace std;

void handler(int signal)
{
    cout << getpid() << " " << signal << endl;
    sleep(1);
}

int main()
{
    signal(8, handler);

    int n = 1;
    n /= 0;

    return 0;
}

在这里插入图片描述
在这里插入图片描述

野指针:

指针异常通常有两种: 无当前虚拟地址的映射关系 或 虚拟地址的操作和页表中的权限不匹配;
当 CPU 的 MMU 寄存器转换地址异常时后, CPU 会将异常的虚拟地址保存至 CR2 寄存器中, 状态设置为异常状态; 之后通知操作系统, 由操作系统向进程发送 SIGSEGV 信号, 该信号默认动作为终止程序;
但若将 SIGSEGV 信号设置自定义动作或忽略, 未处理异常时, 该硬件的异常数据属于进程的上下文; 由于进程依旧运行, 并且 CR2 寄存器依旧为异常状态, 那么操作系统会轮询式的发送异常信号至进程, 直至异常被处理或终止.

#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>

using namespace std;


void handler(int signal)
{
    cout << getpid() << " " << signal << endl;
    sleep(1);
}

int main()
{

    signal(11, handler);

    char* ptr = nullptr;
    *ptr = 0;

    return 0;
}

在这里插入图片描述
在这里插入图片描述

三. 核心转储

core dump(核心转储), 当进程出现异常终止时, 操作系统会将该进程的相关数据保存至当前目录下的一个核心转储文件, 文件名通常为 core 或 core.pid;

核心转储文件的主要目的是为了调试程序, 并且可以直接从出错的地方开始调试, 也叫做事后调试;

当信号的处理动作为 Core 时, 操作系统不仅终止程序, 还会创建核心转储文件; 但由于核心转储文件可能会包含敏感信息, 或文件过大等原因, 此功能通常是关闭的.

例:

  • 核心转储的打开和关闭
    使用指令可以查看当前系统中的资源限制情况, 默认核心转储文件大小为 0;
ulimit -a 

在这里插入图片描述
使用指令可以自行设置核心转储文件大小, 单位为 blocks

ulimit -c /*file_size*/

将核心转储文件大小设为 0, 即可关闭核心转储功能

ulimit -c 0
  • 核心转储的使用
g++ file_name -g 		// 编译文件时使用选项生成可调试文件
						// 运行程序, 生成核心转储文件
gdb file_name  			// 进入调试模式
core-file corefile_name // 使用核心转储文件, 直接定位至出错的地方
  • 父进程也可以通过等待查看子进程是否创建了核心转储文件; 若生成, core dump 标志设为 1, 若没有生成, core dump 标志为 0;
    在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

医药流通企业如何安全访问医药ERP?无需公网IP和改变现有IT架构

随着目前医药流通行业竞争的加剧&#xff0c;市场供应日趋饱和&#xff0c;传统的粗放式管理缺陷逐渐暴露&#xff0c;导致从事医药行业企业的利润不同程度的下滑&#xff0c;想要满足医药行业客户的个性化需求&#xff0c;为适应企业未来发展&#xff0c;医药流通行业越来越多…

Docker 安装 Mongo

创建宿主机目录 在你的宿主机上创建必要的目录来存储 MongoDB 的数据和配置文件。这样做可以保证即使容器被删除&#xff0c;数据也能得到保留。 mkdir -p /develop/mongo/data mkdir -p /develop/mongo/config创建 MongoDB 配置文件 创建一个名为 mongod.conf 的 MongoDB 配…

C语言中整型与浮点型在内存中的存储

今天让我们来看看整型的数据和浮点型的数据在内存中是怎么存储的呢 整型数据在内存中的存储 整型数据在内存中存储的是二进制的补码 正数的话也没什么可说的&#xff0c;原码反码补码都相同 我们来看看负数&#xff1a; 以-5为例 原码&#xff1a;10000000 00000000 00000000 0…

【数据库】Redis

文章目录 [toc]Redis终端操作进入Redis终端Redis服务测试切换仓库 String命令存储字符串普通存储设置存储过期时间批量存储 查询字符串查询单条批量查询 Key命令查询key查询所有根据key首字母查询判断key是否存在查询指定的key对应的value的类型 删除键值对 Hash命令存储hash查…

【HTML】页面引用Vue3和Element-Plus

在现代前端开发中&#xff0c;Vue 3 和 Element Plus 是非常受欢迎的技术。Vue 3 是一个用于构建用户界面的渐进式 JavaScript 框架&#xff0c;而 Element Plus 是一个基于 Vue 3 的组件库&#xff0c;提供了丰富的 UI 组件&#xff0c;帮助开发者快速构建高质量的前端应用。 …

frp 实现 http / tcp 内网穿透(穿透 wordpress )

frp 实现 http / tcp 内网穿透&#xff08;穿透 wordpress &#xff09; 1. 背景简介与软件安装2. 服务端配置2.1 配置文件2.2 wordpress 配置文件2.3 frps 自启动 3.客户端配置3.1 配置文件3.2 frpc 自启动 同步发布在个人笔记frp 实现 http / tcp 内网穿透&#xff08;穿透 w…

多目标粒子群算法及其MATLAB实现

多目标粒子群优化&#xff08;Multi-Objective Particle Swarm Optimization, MOPSO&#xff09;算法是一种基于种群的优化算法&#xff0c;它结合了粒子群优化&#xff08;Particle Swarm Optimization, PSO&#xff09;和多目标优化的思想。多目标粒子群&#xff08;MOPSO&am…

DevOps(八)Jenkins的Maven和Git插件

一、Maven简介 Maven是一个构建生命周期管理和理解工具&#xff0c;用于Java项目。它提供了标准化的构建流程&#xff0c;并简化了从项目编译到文档生成等各种构建方面的管理。 Maven是由Apache软件基金会开发和维护的一个流行的项目管理工具。它的设计目的是简化Java项目的构…

PE结构(二)PE头字段说明

PE头字段 DOS头 PE标记 标准PE头 可选PE头 我们今天分析一下PE头字段中所有重要成员的含义 DOS头 DOS头中我们需要去分析的是如下两个成员&#xff1a; 1.WORD e_magic&#xff1a;MZ标记&#xff0c;用于判断是否为可执行文件&#xff0c;即如果显示4D 5A&#xff0c;…

[2021年最新]国产时序性数据TDenige入门

一、TDenige简介 TDengine&#xff1a;是涛思数据面对高速增长的物联网大数据市场和技术挑战推出的创新性的大数据处理产品&#xff0c;它不依赖任何第三方软件&#xff0c;也不是优化或包装了一个开源的数据库或流式计算产品&#xff0c;而是在吸取众多传统关系型数据库、NoS…

图搜索的经典启发式算法A星(A*、A Star)算法详解

文章目录 1. 引言2. 广度优先搜索3. Dijkstra 算法4. 启发式优先搜索&#xff08;Heuristic&#xff09;4.1 贪心最佳优先搜索4.2 A*搜索 1. 引言 在许多场景中&#xff0c;我们常会遇到一类问题&#xff0c;即“找到一个位置到另一个位置的距离最短&#xff08;用时最少&…

ELK 日志分析系统(二)

一、ELK Kibana 部署 1.1 安装Kibana软件包 #上传软件包 kibana-5.5.1-x86_64.rpm 到/opt目录 cd /opt rpm -ivh kibana-5.5.1-x86_64.rpm 1.2 设置 Kibana 的主配置文件 vim /etc/kibana/kibana.yml --2--取消注释&#xff0c;Kiabana 服务的默认监听端口为5601 server.po…

ubuntu 24.04 beta server NAT模式上网设置

在Ubuntu 24.04 Beta上设置网络通常涉及使用命令行工具。以下是设置静态IP地址和动态IP地址的步骤&#xff1a; 动态IP设置&#xff1a; 查找你的网络接口名称&#xff1a; ip a ens37是我NAT模型的一张网卡&#xff0c;此时是没有ip的。 下面介绍如何NAT模式下添加DHCP动态…

Maven多模块快速升级超好用Idea插件-MPVP

功能&#xff1a;多模块maven项目快速升级指定版本插件&#xff0c;并提供预览和相关升级模块日志能力。 可快速进行版本升级&#xff0c;进行部署到Maven仓库。 安装&#xff1a; 可在idea插件中心进行安装 / 下载资源拖动安装 MPVP(Maven) - IntelliJ IDEs Plugin | Marke…

node.js 解析post请求 方法一

前提&#xff1a;依旧以前面发的node.js服务器动态资源处理代码 具体见 http://t.csdnimg.cn/TSNW9为模板&#xff0c;在这基础上进行修改。与动态资源处理代码不同的是&#xff0c;这次的用户信息我们借用表单来实现。post请求解析来获取和展示用户表单填写信息 1》代码难点&…

快速新建springboot项目

一、初始化 1.打开IDEA&#xff0c;在Spring initializer这里按照下图项目进行配置。注意&#xff1a;如果jdk是1.8建议将Server URL这里替换为图中的阿里云服务器&#xff0c;否则容易找不到对应的java8&#xff0c;然后点击next 2.在这里提前配置一些需要使用的依赖&#xf…

Linux上部署Jupyter notebook

安装jupyter notebook pip install notebook #或者 conda install notebook配置 jupyter notebook --generate-config## The IP address the notebook server will listen on. # Default: localhost # 设置可以访问的ip, 默认是localhost, 将其改为 * c.NotebookApp.ip *#…

CMakeLists.txt中如何添加编译选项?

1. 引子 编译器有多种可供选择&#xff0c;如g、c、clang等&#xff0c;如下以c作为示例。 2. 使用CMAKE_CXX_FLAGS添加编译选项 在Makefile中可能用类似如下的指令来添加编译选项&#xff1a; /usr/bin/c -Wall -Wextra -Wno-sign-compare -Wno-unused-variable -Wno-unuse…

LLM大语言模型(十三):ChatGLM3-6B兼容Langchain的Function Call的一步一步的详细转换过程记录

# LangChain&#xff1a;原始prompt System: Respond to the human as helpfully and accurately as possible. You have access to the following tools: Calculator: Useful for when you need to calculate math problems, args: {\calculation\: {\description\: \calcul…

云安全防御篇:如何识别并做好服务器DDoS防护?

伴随着全球互联网业务和云计算的快速发展&#xff0c;作为一种破坏力巨大的攻击方式&#xff0c;DDoS攻击正以超出服务器承受能力的流量淹没网站&#xff0c;导致服务器宕机、企业营业额下跌&#xff0c;甚至企业品牌形象受损。越是面对复杂的攻击&#xff0c;就需要性能更强的…