Linux信号——信号的产生(1)
注:信号vs信号量:两者没有任何关系!
信号是什么?
Linux系统提供的,让用户(进程)给其他进程发送异步信息的一种方式。
进程看待信号的方式:
1.信号在没有发生的时候,进程已经知道信号发生时该如何处理。
2.进程能够认识进程,很早之前,有人给进程中设置了识别特定信号的方式。
3.信号到来的时候,进程正在处理更重要的事情,进程暂时不能处理到来的信号,进程必须暂时要将到来的信号进行临时保存。
4.信号到了,可以不立即处理,可以在合适的时间处理。
5.信号是随时产生的,进程无法准确预料,所以信号是异步发送的。
为什么要有信号?
系统要求进程要有随时响应外部信号的能力,随后做出反应。
信号的具体知识
以这个时间轴进行学习

信号的产生
常见信号
数组和名字都可以标识信号,名字其实就是宏。
使用kill命令查看信号。

1-31为常用信号,右下的红框中是实时信号。
没有0,没有32,33 信号,共62个信号
信号的处理的方式——signal
a. 默认动作
b. 自定义处理信号——捕捉
c. 忽略了信号——是处理了信号吗?是的,处理方式就是忽略。
实际执行信号的处理动作称之为信号的递达,也就是以上三种方式。
signal函数
#include <signal.h>typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
参数说明:
signum:信号编号(如 SIGINT、SIGTERM)。
handler:信号处理函数,可以是:
SIG_DFL:恢复默认行为。
SIG_IGN:忽略信号。
自定义函数指针:用户定义的处理函数。
返回值:(类型函数指针)
成功时返回之前的处理函数的地址。
失败时返回 SIG_ERR。
产生信号的第一种方式:kill命令
kill -9 进程pid :发送一个信号,杀死一个进程
#include<iostream>
#include<unistd.h>
#include<sys/types.h>
#include<signal.h>
int main()
{while(true){std::cout << "I am activing...,pid:" << getpid() << std::endl;sleep(1);}return 0;
}
结果:
使用命令kill -9 1121788

进程被杀死。
kill -2 进程pid :发送一个信号,默认行为是使进程自己终止。
1.默认行为——进程自己终止
#include<iostream>
#include<unistd.h>
#include<sys/types.h>
#include<signal.h>
int main()
{while(true){std::cout << "I am activing...,pid:" << getpid() << std::endl;sleep(1);}return 0;
}
结果:
在运行的进程中使用kill -2 1121490

进程自己终止。
2.自定义处理信号——捕捉
例子:
#include<iostream>
#include<unistd.h>
#include<sys/types.h>
#include<signal.h>
void handler(int signo)
{std::cout << "get a sig, number is: "<< signo << std::endl;
}
int main()
{//signal调用完了,handler方法会被立即执行吗?不会,只是设置对应信号的处理方法。//未来我们收到对应的信号才执行handler方法。//未来进程如果一直没有收到SIGINT,handler也就永远不会被调用。signal(SIGINT,handler);//handler(SIGINT)while(true){std::cout << "I am activing...,pid:" << getpid() << std::endl;sleep(1);}return 0;
}
结果:
在运行的进程中使用kill -2 1120892

默认行为被更改成其他方法。
3.忽略信号
#include<iostream>
#include<unistd.h>
#include<sys/types.h>
#include<signal.h>
int main()
{signal(SIGINT,SIG_IGN);//ignore忽略while(true){std::cout << "I am activing...,pid:" << getpid() << std::endl;sleep(1);}return 0;
}
结果:
在运行的进程中使用kill -2 1120892

进程无任何反应——这条信号被忽略。
产生信号的第二种方式:键盘产生信号
Ctrl + c 被操作系统解释成2号信号
Ctrl + \ 被操作系统解释成3号信号
产生信号的第三种方式:系统调用
kill 系统调用函数
对任意进程发送任意信号。
#include <sys/types.h>
#include <signal.h>int kill(pid_t pid, int sig);
参数说明:
pid:目标进程的进程 ID,具体行为取决于其取值:
>0:发送信号给 PID 为 pid 的进程。
=0:发送信号给当前进程组内的所有进程。
sig:要发送的信号编号(如 SIGTERM、SIGKILL)。
返回值:
成功返回 0,失败返回 -1,并设置 errno 。
例子:自定义mykill函数
#include<iostream>
#include<unistd.h>
#include<sys/types.h>
#include<signal.h>
#include<errno.h>
#include<string.h>
using namespace std;//mykill -9 pid
int main(int argc,char* argv[])
{if(argc != 3){cout << "Usage: " << argv[0] << " -signumber pid" << endl;return 1;}int signumber = stoi(argv[1]+1);int pid = stoi(argv[2]);int n = kill(pid, signumber);if(n < 0){cerr << "kill error, " << strerror(errno) << endl;}return 0;
}
raise 系统调用函数
对当前进程发送任意信号。
#include <signal.h>int raise(int sig); // 向当前进程发送信号 sig
参数说明:
sig: 信号编号(如 SIGINT、SIGTERM)。
返回值:
成功返回 0,失败返回非 0。
abort系统调用函数
对当前进程发送6号信号。
#include <stdlib.h> // 必须包含的头文件void abort(void);
**参数说明:**无(void)。
**返回值:**无返回值(void)。
产生信号的第四种方式:软件条件
alarm函数
对当前进程等待 seconds 秒后发送14号信号。
#include <unistd.h>unsigned int alarm(unsigned int seconds);
参数说明: seconds – 定时器的时间(秒)。若为 0,表示取消之前设置的定时器。
返回值:
返回之前尚未触发的定时器的剩余秒数。
若之前没有定时器,返回 0。
例子: 向当前进程5秒后发送14号信号,终止进程。
int main()
{alarm(5);//响一次int cnt = 0;while(true){sleep(1);cout<< "cnt: "<< cnt++ << endl;}return 0;
}
结果: 向进程发送了14号信号,终止进程

注:闹钟只响一次。
例: 关于alarm的返回值
#include<iostream>
#include<unistd.h>
#include<sys/types.h>
#include<signal.h>
using namespace std;int g_cnt = 0;
int ret = 0;void handler(int sig)
{std::cout << "get a sig: "<< sig <<" g_cnt: "<< g_cnt <<endl;int n = alarm(2);cout<<"剩余时间:"<< n <<endl;
}int main()
{signal( 2 ,handler);alarm(50);//响一次int cnt = 0;while(true){sleep(1);cout<< "cnt: "<< cnt++ << endl;}return 0;
}
结果: 在 cnt:3 时按下 Ctrl + C

这时获取alarm的返回值是剩余时间。
产生信号的第五种方式:异常
- 除0错误
例子:
#include<iostream>
#include<unistd.h>int main()
{int a = 10;a = a/0;while(true) sleep(1);return 0;}
出现除0错误。
结果:发送8号信号(SIGFPE)

- 野指针问题
例子:
#include<iostream>
#include<unistd.h>int main()
{int *p = nullptr;*p = 100;//野指针while(true) sleep(1);return 0;}
结果:发送11号信号(SIGEGV)

关于信号产生的各种情况的理解
信号保存在进程的PCB中,且以位图的方式保存在PCB中。
在PCB中以 uint32_t pending 变量进行保存。
给进程发送信号,其实就是写入信号。向进程PCB中写入信号数据,PCB是内核数据结构,只有操作系统有权限写入,若用户想写入,操作系统提供系统调用供用户使用。
所以以上的信号产生的5种方式,实际上最终都是交给操作系统进行最后向进程写入信号的操作。
对于异常问题的解释
- 除0错误

- 野指针

总结

相关文章:
Linux信号——信号的产生(1)
注:信号vs信号量:两者没有任何关系! 信号是什么? Linux系统提供的,让用户(进程)给其他进程发送异步信息的一种方式。 进程看待信号的方式: 1.信号在没有发生的时候,进…...
【机器学习】——机器学习思考总结
摘要 这篇文章深入探讨了机器学习中的数据相关问题,重点分析了神经网络(DNN)的学习机制,包括层级特征提取、非线性激活函数、反向传播和梯度下降等关键机制。同时,文章还讨论了数据集大小的标准、机器学习训练数据量的…...
html处理Base文件流
处理步骤 从服务返回的字符串中提取文件流数据,可能是Base64或二进制。将数据转换为Blob对象。创建对象URL。创建<a>元素,设置href和download属性。触发点击事件以下载文件。删除缓存数据 代码 // 假设这是从服务返回的Base64字符串(…...
力扣每日一题:2712——使所有字符相等的最小成本
使所有字符相等的最小成本 题目示例示例1示例2 题解这些话乍一看可能看不懂,但是多读两遍就明白了。很神奇的解法,像魔术一样。 题目 给你一个下标从 0 开始、长度为 n 的二进制字符串 s ,你可以对其执行两种操作: 选中一个下标…...
在MFC中使用Qt(六):深入了解QMfcApp
前言 此前系列文章回顾: 在MFC中使用Qt(一):玩腻了MFC,试试在MFC中使用Qt!(手动配置编译Qt) 在MFC中使用Qt(二):实现Qt文件的自动编译流程 在M…...
JMeter进行分布式压测
从机: 1、确认防火墙是否关闭; 2、打开网络设置,关闭多余端口;(避免远程访问不到) 3、打开JMeter/bin 目录底下的jmeter.properties; remove_hosts设置当前访问地址,192.XXXXX&…...
Python实现音频数字水印方法
数字水印技术可以将隐藏信息嵌入到音频文件中而不明显影响音频质量。下面我将介绍几种在Python中实现音频数字水印的方法。 方法一:LSB (最低有效位) 水印 import numpy as np from scipy.io import wavfile def embed_watermark_lsb(audio_path, watermark, ou…...
快速入手-基于Django-rest-framework的第三方认证插件(SimpleJWT)权限认证扩展返回用户等其他信息(十一)
1、修改serializer.py,增加自定义类 # 自定义用户登录token等返回信息 class MyTokenObtainPair(TokenObtainPairView): def post(self, request, *args, **kwargs): serializer self.get_serializer(datarequest.data) try: serializer.is_valid(raise_exceptio…...
关于IP免实名的那些事
IP技术已成为个人与企业保护隐私、提升网络效率的重要工具。其核心原理是通过中介服务器转发用户请求,隐藏真实IP地址,从而实现匿名访问、突破地域限制等目标。而“免实名”代理IP的出现,进一步简化了使用流程,用户无需提交身份信…...
【SQL性能优化】预编译SQL:从注入防御到性能飞跃
🔥 开篇:直面SQL的"阿喀琉斯之踵" 假设你正在开发电商系统🛒,当用户搜索商品时: -- 普通SQL拼接(危险!) String sql "SELECT * FROM products WHERE name "…...
Spring容器从启动到关闭的注解使用顺序及说明
Spring容器从启动到关闭的注解使用顺序及说明 1. 容器启动阶段 注解:Configuration、ComponentScan 作用: Configuration:标记配置类,声明Spring应用上下文的配置源。ComponentScan:扫描指定包下的组件(B…...
UVM概念面试题100问
1-10:UVM概述 Q1: 什么是UVM? A1: UVM是Universal Verification Methodology的缩写,它是由Accellera标准化的一种用于IC验证的方法学。它提供了一个基类库(BCL),包含通用工具如组件层次结构、事务级模型(TLM)和配置数据库等,使用户能够创建结构化、可重用的验证环境。 Q2:…...
SQL Server从安装到入门一文掌握应用能力。
本篇文章主要讲解,SQL Server的安装教程及入门使用的基础知识,通过本篇文章你可以快速掌握SQL Server的建库、建表、增加、查询、删除、修改等基本数据库操作能力。 作者:任聪聪 日期:2025年3月31日 一、SQL Server 介绍: SQL Server 是微软旗下的一款主流且优质的数据库…...
力扣HOT100之矩阵:54. 螺旋矩阵
这道题之前在代码随想录里刷过类似的,还有印象,我就按照当初代码随想录的思路做了一下,结果怎么都做不对,因为按照代码随想录的边界条件设置,当行数和列数都为奇数时,最后一个元素无法被添加到数组中&#…...
5.1 WPF路由事件以及文本样式
一、路由事件 WPF中存在一种路由事件(routed event),该事件将发送到包含该控件所在层次的所有控件,如果不希望继续向更高的方向传递,只要设置e.Handled true即可。 这种从本控件-->父控件->父的父控件的事件&am…...
Python数据可视化-第1章-数据可视化与matplotlib
环境 开发工具 VSCode库的版本 numpy1.26.4 matplotlib3.10.1 ipympl0.9.7教材 本书为《Python数据可视化》一书的配套内容,本章为第1章 数据可视化与matplotlib 本文主要介绍了什么是数据集可视化,数据可视化的目的,常见的数据可视化方式…...
Flutter敏感词过滤实战:基于AC自动机的高效解决方案
Flutter敏感词过滤实战:基于AC自动机的高效解决方案 在社交、直播、论坛等UGC场景中,敏感词过滤是保障平台安全的关键防线。本文将深入解析基于AC自动机的Flutter敏感词过滤实现方案,通过原理剖析实战代码性能对比,带你打造毫秒级…...
20250331-vue-组件事件1触发与监听事件
触发与监听事件 1 在组件的模板表达式中,可以直接使用 $emit 方法触发自定义事件(例如:在 v-on 的处理函数中): 子组件代码 <template><button click"$emit(someEvent)">点击</button> </template><…...
Odoo/OpenERP 和 psql 命令行的快速参考总结
Odoo/OpenERP 和 psql 命令行的快速参考总结 psql 命令行选项 选项意义-a从脚本中响应所有输入-A取消表数据输出的对齐模式-c <查询>仅运行一个简单的查询,然后退出-d <数据库名>指定连接的数据库名(默认为当前登录用户名)-e回显…...
Vue中使用antd-table组件时,树形表格展开配置不生效-defaultExpandedRowKeys-默认展开配置不生效
defaultExpandedRowKeys属性 defaultExpandAllRows这个属性仅仅是用来设置默认值的,只在第一次渲染的时候起作用,后续再去改变,无法实现响应式 解决方案一 a-table表格添加key属性,当每次获取值时,动态改变key,以达到重新渲染的效果 <a-table:key="tableKey"…...
VRRP交换机三层架构综合实验
题目要求: 1,内网Ip地址使用172.16.0.0/16分配 说明可以划分多个子网,图中有2个VLAN,可以根据VLAN划分 2,sw1和SW2之间互为备份 互为备份通常通过VRRP(虚拟路由冗余协议)来实现。VRRP会在两个…...
基于卷积神经网络的眼疾识别系统,resnet50,efficentnet(pytorch框架,python代码)
更多图像分类、图像识别、目标检测、图像分割等项目可从主页查看 功能演示: 眼疾识别系统resnet50,efficentnet,卷积神经网络(pytorch框架,python代码)_哔哩哔哩_bilibili (一)简介…...
基于srpingboot智慧校园管理服务平台的设计与实现(源码+文档+部署讲解)
技术范围:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论…...
【力扣hot100题】(026)合并两个有序链表
可以创建一个新链表记录答案: /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* ListNode(int x, ListNode *…...
TCP网络编程与多进程并发实践
一、引言 在网络编程中,TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。而多进程并发则是一种提高服务器处理能力的有效手段,允许服务器同时处理多个客户端的请求。本文将详细介绍如何使用 TCP 协议进…...
【前端】一文掌握 Vue 3 指令用法(vue3 备忘清单)
文章目录 入门介绍创建应用应用实例通过 CDN 使用 Vue使用 ES 模块构建版本模板语法文本插值原始 HTMLAttribute 绑定布尔型 Attribute动态绑定多个值使用 JavaScript 表达式仅支持表达式(例子都是无效)调用函数指令 Directives参数 Arguments绑定事件动态参数动态的事件名称修…...
visio导出pdf公式变形
情况描述导出为pdf后,mathtype写的公式就变形了 但是导出为png和jpg就是正常 解决方法就是 需要下载一个Adobe Acrobat...
【学习笔记】计算机网络(六)
第6章应用层 文章目录 第6章应用层6.1 域名系统DNS6.1.1 域名系统概述6.1.2 互联网的域名结构6.1.3 域名服务器域名服务器的分区管理DNS 域名服务器的层次结构域名服务器的可靠性域名解析过程-两种查询方式DNS 高速缓存机制 6.2 文件传送协议6.2.1 FTP 概述6.2.2 FTP 的基本工作…...
做一个多级动态表单,可以保存数据和回显数据
<template> <div class"two"> <button class"save" click"saveBtn">保存数据</button> <button class"sd" click"showBtn">回显数据</button> <div class"all" click&quo…...
量子退火与机器学习(2):少量实验即可找到新材料,黑盒优化➕量子退火
使用量子退火和因子分解机设计新材料 这篇文章是东京大学的一位博士生的毕业论文中的主要贡献。 结合了黑盒优化和量子退火,是融合的非常好的一篇文章,在此分享给大家。 https://journals.aps.org/prresearch/abstract/10.1103/PhysRevResearch.2.0133…...
