【视频笔记】408新增知识点信号——里昂视频

news2024/10/11 15:30:07

文章目录

        • **2.信号**
        • **3.信号的实现**
        • 4.信号的处理
          • **①忽略信号**
          • **②执行信号的默认操作**
          • **③捕获井处理信号**
          • 几个Linux支持的典型信号:
        • **5.信号的产生**
          • ① **通过终端按键(键盘)产生信号**例如,`Ctrl+C`发送2号信号SIGINT、`Ctrl+\`发送3号信号SIGQUIT
          • ② **程序异常时**操作系统会向程序发送信号来终止进程。
          • ③ **调用函数**
            • - kill系统调用:
            • - raise系统调用
            • abort 系统调用
          • ④由于软件条件产生信号
            • exp1
            • exp2
          • ⑤ 硬件异常产生信号

原视频来自于B站里昂,总长22min
视频链接

在这里插入图片描述

进程通信方法:管道,共享内存,消息队列,信号和信号量

在这里插入图片描述


2.信号

一个信号就是一条小消息,它通知进程系统中发生了一个某种类型的事件。比如,如果当进程在前台运行时,你键入Ctrl+C(也就是同时按下Ctrl键和 C键),那么内核就会发送一个SIGINT信号给这个前台进程

在这里插入图片描述
在linux系统中使用 kill -l 命令查看系统上支持的不同类型的信号。

每种信号类型都对应于某种系统事件,用不同的整数表示,例如SIGINT信号用号码2表示

1~31号为非实时信号(不可靠信号)处于就绪队列多个相同的非实时信号只会被响应一次。其余的被丢掉。
34~64号信号为实时信号(可靠信号),处于就绪队列多个相同的实时信号全部会被响应。

在这里插入图片描述

比如,如果一个进程试图除以0,那么内核就发送给它一个SIGFPE信号(号码8 Floating Point Exception浮点异常)。
如果一个进程执行一条非法指令,那么内核就发送给它一个SIGILL信号(号码4)。
sigill(ill生病,有病的,不健康的;不良的;不良的;〈美俚〉(因嫌疑而)被捕的,被拘留的;坏的,邪恶的,有害的;不舒服;)

kill -l
#查看系统上支持的不同类型的信号
3.信号的实现

在操作系统中,每个进程都有一个进程控制块(Process Control Block,PCB),它包含了进程的管理和控制信息.。
【例】Linux下,用一个名为task_struct的结构体类型来描述PCB,包括很多字段,如进程的状态进程的标识、进程的优先级等。每一种信息都用一个字段来实现。

struct task struct
{
...
volatile long state; /进程状态
pid_t pid; //进程ID,每个进程都有一个唯一的PID,用于区分不同进程,相当于身份证号
unsigned long rt_priority;//进程优先级
stuct mm_struct*mm,*active_mm;//与内存管理有关的数据结构,包含进程内存使用的信息
...
}

因此,我们可以将信号记录在进程的task_struct(PCB)结构体中。
例如,我们可以用位图来表示某个信号是否产生,每个比特位代表了某个特定的信号,比特位为0代表没有收到了信号,为1则代表收到了信号。进程收到信号,本质是位图被修改

在这里插入图片描述

4.信号的处理

通常有以下三种操作处理信号:

①忽略信号

不采取任何操作。但是有两种信号不能被忽略:SIGKILL(9)和SIGSTOP(19)
这样做的原因是系统管理员需要能够杀死或停止进程,如果进程能够选择忽略SIGKILL(使进程不能被杀死)或SIGSTOP(使进程不能被停止)将破坏这一权力。

②执行信号的默认操作

例如,进程收到SIGINT信号后会终止,本质上是向进程发送了一个编号为2的SIGINT信号,只不过这个信号是通过键盘输入的,然后经过操作系统处理后再发送给进程。
在这里插入图片描述

③捕获井处理信号

内核会暂停该进程正在执行的代码,并跳转到用户注册的函数。

SIGINT原本是用来结束进程的,但用signal自定义它的功能后就可以使它对进程的操作改变,

在这里插入图片描述

#include<singal.h>
#include<stdio.h>
#include<unistd.h>
//handle的函数实现的功能是打印can't stop!"
void handle(int sigNum){
printf("can't stop! sigNum:%d\n",sigNum);
}
int main(){
	signal(SIGINT,handle);
//将SIGINT号信号的功能改成handle
	while(1){
		printf("a\n");
		sleep(1);
	}
return 0;

}

可以看到,每次按下Ctrl+C,都会打印对应内容(实现自定义的功能而不是像原来一样终止进程),而sigNum也证明Ctrl+C对应的信号值确实是2号(SIGINT)。
在这里插入图片描述

经常捕获的两种信号是 SIGINT 和 SIGTERM。

SIGKILL和SIGSTOP 不能被捕获,即无法通过自定义handle函数来修改其信号操作。

exp1

#include<singal.h>
#include<stdio.h>
#include<unistd.h>
//handle的函数实现的功能是打印can't stop!"
void handle(int sigNum){
printf("can't stop! sigNum:%d\n",sigNum);
}
int main(){
	signal(SIGKILL,handle);
//将SIGINT号信号的功能改成handle
	while(1){
		printf("still alive\n");
		sleep(1);
	}
return 0;

}

在这里插入图片描述


exp2

#include<singal.h>
#include<stdio.h>
#include<unistd.h>
int count=0;
//handle的函数实现的功能是打印"count=%d, still alive"
void handle(int sigNum){
printf("count=%d, still alive sigNum:%d\n",sigNum);
}
int main(){
	signal(SIGKILL,handle);
	signal(SIGTERM,handle);
	signal(SIGINT,handle);
//将SIGINT号信号的功能改成handle
	while(1){
		count++;
		sleep(1);
	}
return 0;

}

在这里插入图片描述
2:sigint
15:sigterm
9:sigkill


几个Linux支持的典型信号:

在这里插入图片描述

SIGCHLD
当进程终止或停止时,内核会给进程的父进程发送此信号。在默认的情况下SIGCHLD是被忽略的,如果进程对它们的子进程是否存在感兴趣,那么进程必须显式地捕获并处理该信号。
SIGFPE
不考虑它的名字,该信号代表所有的算术异常,而不仅仅指浮点数运算相关的异常,异常包括溢出、下溢和除以0.
默认的操作是终止进程并形成内存转储文件,但进程可以捕获并处理该信号。
SIGILL
当进程试图执行一条非法机器指令时,内核会发送该信号。默认操作是终止进程并进行内存转储进程可以选择捕获并处理SIGILL。
SIGINT
当用户输入中断符(通常是Ctrl-C)时,该信号被发送给所有前台进程组中的进程默认的操作是终止进程。进程可以选择捕获并处理该信号,通常是为了在终止前进行清理工作

5.信号的产生

信号通常由以下方式产生:

通过终端按键(键盘)产生信号例如,Ctrl+C发送2号信号SIGINT、Ctrl+\发送3号信号SIGQUIT
程序异常时操作系统会向程序发送信号来终止进程。
调用函数
- kill系统调用:

kil()调用会从一个进程向另一个进程发送信号:
int kill(pid t pid,int signo);//调用kill给pid代表的进程发送信号signo。
kill命令本质上是通过系统调用实现的。

- raise系统调用

【例子】创建一个raise程序,将其2号信号的处理函数改为自定义函数,该信号每隔一段时间便会给自己发送信号

#include<singal.h>
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>

void handle(int signo){
printf("get a signal : %d\n", signo);
}
int main(){
	signal(2,handle);
//将2号信号自定义。
	while(1){
		printf("I'm a process, pid = %d\n",getpid());
		sleep(1);
		raise(2);
		//进程自己给自己发送2号信号。
	}
return 0;

}
abort 系统调用

abort 使当前进程接受到信号而异常终止

#include<singal.h>
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>

void handle(int signo){
printf("get a signal : %d\n", signo);
}
int main(){
	signal(6,handle);
//将SIGINT号信号的功能改成handle
	while(1){
		printf("I am a process, pid : %d\n",getpid());
		sleep(1);
		abort();
	}
return 0;

}

在这里插入图片描述

④由于软件条件产生信号

例如alarm()函数可以设置定时器,当定时器倒计时结束,就会向进程发送一个SIGALARM信号。

exp1
#include<singal.h>
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>

void handle_alarm(int signo){
printf("Alarm clock!\n");
}
int main(){
//设置信号处理函数
	signal(SIGALRM,handle_alarm);
//做其他事情或者简单地等待
	while(1){
		printf("running\n");
		alarm(2);
		sleep(2);
	}
return 0;

}
exp2

pause()函数的作用是使当前进程进入睡眠状态,直到接收到一个信号为止。

int pause(void);
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
int main( ) {
	pid_t child_pid = fork();
	//fork一个子进程。 子进程的pid不一样。
	if(child_pid < 0) {//创建新进程失败。
		perror("Fork failed");
		exit(1);
	}
	if (child pid == 0){ // 子进程
		while (1){
			pause(); // 等待信号
	}else { // 父进程
		while (1) {
			sleep(2);//每2秒发送一次信号
			kill(child_pid, SIGUSR1);// 向子进程发送信号
			printf("Sent SlGUSR1 to child process (PID: %d)\n", child_pid);
			}
	return 0;
}
⑤ 硬件异常产生信号

发生硬件异常时,它被硬件以某种方式检测到并通知内核,然后内核向当前进程发送适当的信号。
例如当前进程执行了除零的指令CPU的运算单元会产生异常,内核将这个异常解释为SIGFPE信号,并将该信号发送给进程。

总之,使用信号的两个主要目的:
① 让进程知道已经发生了一个特定的事件。
② 强迫进程执行它自己代码中的信号处理程序,
注意,并不是系统中所有进程都可以向其他进程发送信号,只有核心和超级用户可以。

普通进程只可以向拥有相同uid(用户标识号)和gid(组标识号)或者在相同进程组中的进程发送信号。

当信号产生时,内核将进程taskstruct中的信号相应标志位设置为1,表明产生了该信号。

系统对置位之前该标志位已经为1的情况不进行处理,这说明进程只处理最近接收的信号。
信号产生后并不马上送给进程,它必须等待直到进程再一次运行时才交给它。
每当进程从系统调用中退出时,内核会检查它的signal和blocked字段(位图),查看是否有需要发送的非屏蔽信号,若有则立即发送信号。

如果信号的处理被设置为缺省,则系统内核将会处理该信号,否则会执行用户提供的信号处理程序。

【练习1】信号是用户按下Ctrl+C时默认发送给前台进程组的信号?
A. ‘SIGKILL’
B.'SIGSTOP’
C.‘SIGINT’
D.‘SIGTERM’
答案:C

【练习2】哪个信号用于终止进程,并且不能被进程捕获或忽路?
A. 'SIGKILL`
B.“SIGBUS”
C. 'SIGINT
D.'SIGTERM
答案:A

【练习3】在信号的进程通信机制中,以下哪个说法是正确的?
A.对于任意的信号都可以忽略
B.对于任意的信号都可以捕获
C.系统中所有进程都可以向其他进程发送信号
D.系统对置位之前该标志位已经为1的情况不进行处理,这说明进程只处理最近接收的信号
答案:D

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

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

相关文章

Matlab实现海洋捕食者优化算法优化回声状态网络模型 (MPA-ESN)(附源码)

目录 1.内容介绍 2部分代码 3.实验结果 4.内容获取 1内容介绍 海洋捕食者优化算法&#xff08;Marine Predators Algorithm, MPA&#xff09;是一种基于海洋生物捕食行为的新型群体智能优化算法。MPA通过模拟海洋捕食者如鲨鱼、海豚等在寻找猎物时的追踪、包围和攻击行为&…

双十一购买清单,应该如何选购宠物空气净化器,有哪几款推荐

作为一个宠物博主&#xff0c;每天都有人来问我家里养了猫应该怎么样才能清理浮毛&#xff0c;到底有哪些值得推荐。 这我可是有话说&#xff0c;当初就是心血来潮养了两只长毛猫&#xff0c;直到现在都还一直在清理猫咪掉毛的问题。猫咪掉的毛&#xff0c;不仅是会掉在沙发上…

EmEditor传奇脚本编辑器

主程序&#xff1a;EmEditor.exe 目前已有功能 可以自己指定一个快捷键 实现以下功能&#xff08;默认快捷键为&#xff1a;F1&#xff09; 以下全功能 都是鼠标所在行 按快捷键 &#xff08;默认快捷键&#xff1a;F1&#xff09; 1.在Merchant.txt中 一键打开NPC 没有…

11.Lab Ten —— mmap

内存映射文件&#xff08;Memory-Mapped File&#xff09;是一种将文件内容映射到进程的虚拟地址空间的技术&#xff0c;使得文件的内容可以像内存一样被访问。 通过内存映射文件&#xff0c;可以高效地访问和操作文件内容 首先切换到mmap分支 git checkout mmap make clean…

【机器学习】随机森林算法(看我以弱博强)

目录 算法引入&#xff1a; 算法介绍&#xff1a; 1. 集成学习&#xff1a; 2. 训练过程&#xff1a; 3. 分类和回归&#xff1a; 算法优点&#xff1a; 算法缺点&#xff1a; 算法实现&#xff1a; 1. 数据准备 2. 划分数据集 3. 创建随机森林模型 4. 训练模型 5…

Kubesphere4.1版本创建应用Mysql并实现外网访问

目前Kubesphere4.1版本可查创建应用资料较少&#xff0c;特此记录作为参考。 目标 使用Kubesphere4.1完成Mysql服务部署并实现外网访问。 具体流程如下&#xff1a; 1.创建企业空间 2.创建项目 3.创建应用仓库 4.创建应用&#xff08;mysql&#xff09; 5.配置外网访…

抖去推--短视频矩阵系统源码对外资料包

#短视频矩阵系统源码# #短视频矩阵系统源码开发# #短视频矩阵系统源码打包# 一、短视频矩阵系统源码安装 安装环境 短视频矩阵系统源码需要以下环境&#xff1a; PHP 7.0 及以上 MySQL 5.5 及以上 Nginx / Apache Redis FFMpeg 下载源码 从官网下载最新版本的短视频矩阵系统…

浅谈云原生--微服务、CICD、Serverless、服务网格

往期推荐 浅学React和JSX-CSDN博客 一文搞懂大数据流式计算引擎Flink【万字详解&#xff0c;史上最全】-CSDN博客 一文入门大数据准流式计算引擎Spark【万字详解&#xff0c;全网最新】_大数据 spark-CSDN博客 目录 1. 云原生概念和特点 2. 常见云模式 3. 云对外提供服务的…

【linux】麒麟v10安装prometheus监控(ARM架构)

Prometheus介绍 Prometheus 是一个开源的系统监控和警报工具包&#xff0c;最初由 SoundCloud 开发&#xff0c;现在是一个独立的开源项目&#xff0c;并且是云原生计算基金会&#xff08;CNCF&#xff09;的一部分。Prometheus 以其强大的数据模型和灵活的查询语言&#xff0…

线下餐厅自主点餐或外卖配送小程序源码系统 带完整的安装代码包以及搭建部署教程

系统概述 线下餐厅自主点餐或外卖配送小程序源码系统是一款专为餐饮行业打造的智能化解决方案。它融合了自主点餐、外卖配送、订单管理、数据分析等多种功能&#xff0c;为餐厅提供了一站式的服务平台。通过该系统&#xff0c;餐厅可以实现线上线下一体化运营&#xff0c;提高工…

猿人学 — 第1届第3题(解题思路附源码)

猿人学 — 第1届第3题 翻页发现一共有两个请求 第一个请求&#xff1a;返回状态码为202&#xff08;服务器已经接收请求&#xff0c;但尚未处理&#xff09;&#xff0c;响应头中还有一个Set-Cookie 第二个请求&#xff1a;返回了我们想要的数据&#xff0c;携带的Payload中…

基于M芯片MAC系统的hadoop、zookeeper、hbase安装

hadoop、zookeeper、hbase安装 1. vmware配置 搜索&#xff1a;“vmware for mac”&#xff0c;购买正版并下载&#xff0c;或通过其他渠道下载均可 随机掉落的奇怪链接 2. 下载镜像并安装虚拟机 bug记录1 此处选用ubuntu的20以及24&#xff0c;分别出现无法加载安装程序、…

会话管理:深入理解SQLAlchemy会话及其事务处理

引言 SQLAlchemy是一个流行的Python SQL工具包和对象关系映射&#xff08;ORM&#xff09;系统&#xff0c;它提供了一个高层的ORM以及底层的SQL表达式语言。在SQLAlchemy中&#xff0c;会话&#xff08;Session&#xff09;是与数据库交互的核心概念&#xff0c;它不仅负责对…

外卖配送小程序源码系统 带源代码包以及搭建部署教程

系统概述 外卖配送小程序源码系统是一套完整的解决方案&#xff0c;旨在帮助用户快速搭建自己的外卖配送平台。它融合了先进的技术和创新的设计理念&#xff0c;为用户提供了一个稳定、高效、易用的系统环境。 该系统基于移动端开发&#xff0c;能够与各种操作系统兼容&#…

2.stm32 GPIO输出

GPIO简介 GPIO&#xff08;General Purpose Input Output&#xff09;通用输入输出口 可配置为8种输入输出模式 引脚电平&#xff1a;0V~3.3V&#xff0c;部分引脚可容忍5V 输出模式下可控制端口输出高低电平&#xff0c;用以驱动LED、控制蜂鸣器、模拟通信协议输出时序等 …

网络变压器的作用是什么

在网络通讯主板上,在PHY芯片与RJ45连接器之间,会有一个黑属的小方块,这个东西就叫网络变压器,书名"数据录”人们常把它称为网络隔真变压务,LAN变压客,局域网变压器,滤波器等。 它在一块网络设备接口上所起的作用主要有两个; 一、传输数据,它把PHY送出来的差分信号用差模合…

电子元器件是电子电路中的基本组成部分

电子元器件是电子电路中的基本组成部分&#xff0c;主要包括以下几类&#xff1a; 一、电阻器 作用 限流&#xff1a;限制电路中的电流大小。分压&#xff1a;将电压按照一定比例分配。负载&#xff1a;作为电路中的负载元件。 分类 固定电阻&#xff1a;阻值固定不变。可变电阻…

ros1编译wpr_simulation库

目录 安装项目依赖包编译将环境参数加载到终端程序中运行编译好的ros程序 首先你下载好这个库以后。 安装项目依赖包 scripts库中&#xff0c;存放的是一些依赖项安装脚本以及python脚本。 进入到这个路径的终端。 输入 ./install_for_noetic.sh编译 输入下面命令&#xf…

小猿口算自动PK脚本

大家好&#xff0c;我是小黄。 近期&#xff0c;众多大学生炸鱼小猿口算APP,把一众小学生都快虐哭了&#xff0c;小黄听闻后&#xff0c;也跃跃欲试。对此小黄也参考网上的资料写了一个自动Pk的脚步。 首先大家需要安装一个pytorch环境过程中&#xff0c;如果小伙伴对此不熟悉的…