当前位置: 首页 > news >正文

Linux进程信号(三)之信号产生2

文章目录

      • 4. 由软件条件产生信号
      • 5. 硬件异常产生信号
        • 模拟一下除0错误和野指针异常
          • 除0错误
          • 野指针错误
      • 总结思考一下

4. 由软件条件产生信号

SIGPIPE是一种由软件条件产生的信号,在“管道”中已经介绍过了。

image-20250421161453471

软件条件不就绪,很明显这个软件条件没有直接报错,而是通过返回值来反映。

#include <iostream>
#include <signal.h>
#include<unistd.h>using namespace std;int main()
{char buffer[1024];int n=1024;n=read(4,buffer,sizeof(buffer));printf("n=%d\n",n);perror("read");return 0;
}

image-20250421162729359

软件条件可能会产生信号也可能不会,取决于操作系统本身。

操作系统是由对软件检测的能力的,所以能通过软件条件产生信号。

本节主要介绍alarm函数 和SIGALRM信号。

image-20250421163823918

image-20250421164025016

#include <unistd.h>
unsigned int alarm(unsigned int seconds);
调用alarm函数可以设定一个闹钟,
也就是告诉内核在seconds秒之后给当前进程发SIGALRM信号, 
该信号的默认处理动作是终止当前进程。

这个函数的返回值是0或者是以前设定的闹钟时间还余下的秒数。

打个比方:

某人要小睡一觉,设定闹钟为30分钟之后响,

20分钟后被人吵醒了,还想多睡一会儿,

于是重新设定闹钟为15分钟之后响,“以前设定的闹钟时间还余下的时间”就是10分钟。

如果seconds值为0,表示取消以前设定的闹钟,

函数的返回值仍然是以前设定的闹钟时间还余下的秒数

例 alarm

#include <iostream>
#include <signal.h>
#include<unistd.h>using namespace std;
int main()
{alarm(5);while(1){cout<<"proc is running"<<endl;sleep(1);}return 0;
}

image-20250421164457780

验证:收到了14号信号

#include <iostream>
#include <signal.h>
#include<unistd.h>using namespace std;void handler(int signum)
{cout<<"get a sig,num: "<<signum<<endl;
}int main()
{signal(14,handler);alarm(5);while(1){cout<<"proc is running"<<endl;sleep(1);}return 0;
}

image-20250421164824619

因为只设置一次,闹钟只响了一次(因为不是异常)

如果想让闹钟每隔5秒响一次

(收到了14号信号,就去调用处理方法,

在调用方法里,又设置了一个闹钟,5秒之后,又收到了14号信号,继续调用处理方法……)

void handler(int signum)
{cout<<"get a sig,num: "<<signum<<endl;alarm(5);
}

image-20250421165141207

查看剩余时间

收到了14号信号,那么调用处理方法,闹钟将会重新设置,alarm(5)

#include <iostream>
#include <signal.h>
#include<unistd.h>using namespace std;void handler(int signum)
{cout<<"get a sig,num: "<<signum<<endl;int n=alarm(5);cout<<"time: "<<n<<endl;
}int main()
{signal(14,handler);int n=alarm(50);while(1){cout<<"proc is running,pid: "<<getpid()<<endl;sleep(1);}return 0;
}

image-20250421170457161

操作系统内部会有很多闹钟,所以OS要管理闹钟,

先描述再组织,对闹钟的管理就变成了对链表的增删查改。

闹钟的描述:有指向进程的指针,有时间(使用时间戳)

时间戳+设定的时间=未来时间

如果现在时间大于等于这个未来时间就表示超时了。

遍历链表对比时间,如果时间到了就发送信号,该节点就可以从链表里删除了。

提高效率:

使用优先级队列或者堆等数据结构。

最小堆,将数据结构都放进最小堆,

堆顶数据没有超时,那么整个堆都没有超时。

堆顶超时了,只要将堆顶处理,就可以移除堆顶元素。

5. 硬件异常产生信号

硬件异常被硬件以某种方式被硬件检测到并通知内核,

然后内核向当前进程发送适当的信号。

例如当前进程执行了除以0的指令,

CPU的运算单元会产生异常,

内核将这个异常解释 为SIGFPE信号发送给进程。

再比如当前进程访问了非法内存地址,

MMU会产生异常,内核将这个异常解释为SIGSEGV信号发送给进程。

捕捉信号,不是为了解决出现的问题,

而是为了让用户知道进程为什么挂了。(做做收尾工作)

模拟一下除0错误和野指针异常

makefile

mysignal:mysignal.ccg++ -o $@ $^ -std=c++11
.PHONY:clean
clean:rm -rf mysignal
除0错误

mysignal.cc

#include <iostream>
#include <signal.h>
#include<unistd.h>using namespace std;int main()
{cout<<"div before"<<endl;sleep(1);int a=10;a/=0;cout<<"div after"<<endl;sleep(1);return 0;
}

image-20250420223834069

证明收到了8号信号

image-20250420224125165

mysignal.cc

#include <iostream>
#include <signal.h>
#include<unistd.h>using namespace std;void handler(int signum)
{cout<<"get a sig,num: "<<signum<<endl;//只是打印了一行信息,其他什么都没干
}int main()
{signal(8,handler);cout<<"div before"<<endl;// sleep(1);int a=10;a/=0;cout<<"div after"<<endl;// sleep(1);return 0;
}

image-20250420225220573

代码为什么一直都不退出呢?

因为8号信号的默认动作是退出,但是现在改成了自定义动作,

自定义动作只有打印信息没有设置退出,所以进程不会退出。

野指针错误

mysignal.cc

#include <iostream>
#include <signal.h>
#include<unistd.h>using namespace std;int main()
{cout<<"point error before"<<endl;int *p=nullptr;//p指向0号地址*p=100;//没有资格访问0号地址(权限问题/野指针问题)cout<<"point error after"<<endl;return 0;
}

image-20250420230117465

验证收到11号信号

image-20250420230550597

mysignal.cc

#include <iostream>
#include <signal.h>
#include<unistd.h>using namespace std;void handler(int signum)
{cout<<"get a sig,num: "<<signum<<endl;//只是打印了一行信息,其他什么都没干
}int main()
{signal(11,handler);cout<<"point error before"<<endl;int *p=nullptr;//p指向0号地址*p=100;//没有资格访问0号地址(权限问题/野指针问题)cout<<"point error after"<<endl;return 0;
}

image-20250420230416654

以上证明,进程出了异常不一定会退出,只要捕捉信号即可。

(但是不退出意义不大了,还占用着CPU的资源)

不退出就会一直被调度运行,硬件异常没有被修正,

然后运行又有硬件报错,然后OS一直发信号,

进程收到信号继续被捕捉……如此循环。

由此可以确认,我们在C/C++当中除零,内存越界等异常,

在系统层面上,是被当成信号处理的。


为什么除0和野指针会让进程崩溃呢?

因为收到了信号,该信号的默认处理动作是终止进程自己。

为什么除0和野指针会给进程发信号呢?

因为硬件发生了报错,OS检测到了,所以给进程发信号。

OS怎么知道发生了除0和野指针?

除0:

image-20250421102446425

所以,除0错误最终会被转化成硬件问题,

OS识别到了硬件报错,

所以OS要给进程发信号,

所以进程收到信号会自己终止(崩溃)。

野指针:

image-20250421105356726

CPU内部不同的寄存器的报错代表不同的信号。

总结思考一下

上面所说的所有信号产生,最终都要有OS来进行执行,为什么?

因为OS是进程的管理者!

OS是进程的管理者信号的处理是否是立即处理的?

不是立即处理。进程可能正在做更重要的事。

在合适的时候,信号如果不是被立即处理,那么信号是否需要暂时被进程记录下来?记录在哪里最合适呢?

一个进程在没有收到信号的时候,能否能知道,自己应该对合法信号作何处理呢?

如何理解OS向进程发送信号?能否描述一下完整的发送处理过程?

相关文章:

Linux进程信号(三)之信号产生2

文章目录 4. 由软件条件产生信号5. 硬件异常产生信号模拟一下除0错误和野指针异常除0错误野指针错误 总结思考一下 4. 由软件条件产生信号 SIGPIPE是一种由软件条件产生的信号,在“管道”中已经介绍过了。 软件条件不就绪&#xff0c;很明显这个软件条件没有直接报错&#xff…...

【AWS入门】Amazon SageMaker简介

【AWS入门】Amazon SageMaker简介 [AWS Essentials] Brief Introduction to Amazon SageMaker By JacksonML 机器学习(Machine Learning&#xff0c;简称ML) 是当代流行的计算机科学分支技术。通常&#xff0c;人们在本地部署搭建环境&#xff0c;以满足机器学习的要求。 AWS…...

MySQL--day2--基本的select语句

&#xff08;以下内容全部来自上述课程&#xff09; SQL概述 结构化查询语句 1. SQL分类 DDL&#xff1a;数据定义&#xff08;definition&#xff09;语言&#xff1a;create、drop、alter… DML&#xff1a;数据操作&#xff08;manipulation&#xff09;语言&#xff…...

程序代码篇---python获取http界面上按钮或者数据输入

文章目录 前言 前言 本文简单接受了python获取http界面上按钮或者数据输入...

网络安全利器:蜜罐技术详解

蜜罐是网络安全领域中一种主动防御和情报收集的重要工具。本文将深入探讨蜜罐技术的原理、类型、应用场景以及部署注意事项。 1. 什么是蜜罐? 蜜罐(Honeypot)是一种安全资源,其价值在于被探测、攻击或未经授权使用。简单来说,蜜罐就是一个诱饵系统,用来吸引黑客的注意力…...

回溯实战篇3

文章目录 前言排列全排列全排列II 棋盘问题N皇后解数独 其他递增子序列重新安排行程 前言 今天继续带大家进行回溯的实战篇3&#xff0c;去学习如何用回溯的方法去解决排列和棋盘以及其他用回溯方法解决的问题&#xff0c;最重要的就是学会回溯三部曲的构建&#xff0c;一文带…...

Spark 基础自定义分区器

&#xff08;一&#xff09;什么是分区 【复习提问&#xff1a;RDD的定义是什么&#xff1f;】 在 Spark 里&#xff0c;弹性分布式数据集&#xff08;RDD&#xff09;是核心的数据抽象&#xff0c;它是不可变的、可分区的、里面的元素并行计算的集合。 在 Spark 中&#xf…...

【提高+/省选−】洛谷P1495 —— 【模板】中国剩余定理(CRT)/ 曹冲养猪

见&#xff1a;P1495 【模板】中国剩余定理&#xff08;CRT&#xff09;/ 曹冲养猪 - 洛谷 题目描述 自从曹冲搞定了大象以后&#xff0c;曹操就开始捉摸让儿子干些事业&#xff0c;于是派他到中原养猪场养猪&#xff0c;可是曹冲满不高兴&#xff0c;于是在工作中马马虎虎&a…...

系统架构设计师考前冲刺笔记-第1章-系统工程与信息系统基础

文章目录 第1章 系统工程与信息系统基础大纲13 DSS5678 BSP910 SCM11 OLAP12 OLAP14 BRP15 集成16 企业门户19 边缘计算 第1章 系统工程与信息系统基础 大纲 1 3 DSS DSS 决策支持系统 Decision Support System 5 6 7 8 BSP 9 10 SCM 注意&#xff1a;生产计划 11 OLAP O…...

Vue环境下数据导出Excel的全面指南

文章目录 1. 前言2. 原生JavaScript实现方案2.1 使用Blob对象和URL.createObjectURL2.2 使用Base64编码实现 3. 常用第三方库方案3.1 使用SheetJS (xlsx)3.2 使用ExcelJS3.3 使用vue-json-excel 4. 服务器端导出方案4.1 前端请求服务器生成Excel4.2 使用Web Worker处理大数据导…...

Linux下 使用 SSH 完成 Git 绑定 GitHub

文章目录 1、检查 SSH2、生成 SSH key3、添加 SSH key4、验证绑定是否成功 1、检查 SSH Git Bash 中输入ssh命令&#xff0c;查看本机是否安装 SSH&#xff1a; 2、生成 SSH key &#xff08;1&#xff09;输入 ssh-keygen -t rsa 命令&#xff0c;表示我们指定 RSA 算法生…...

Jsoup库和Apache HttpClient库有什么区别?

Jsoup 和 Apache HttpClient 是两个功能不同的库&#xff0c;它们在 Java 开发中被广泛使用&#xff0c;但用途和功能有明显的区别&#xff1a; Jsoup 用途&#xff1a;Jsoup 是一个用于解析 HTML 文档的库。它提供了非常方便的方法来抓取和解析网页内容&#xff0c;提取和操作…...

安全漏洞频发,如何加强防护措施?

当系统安全漏洞频发时&#xff0c;应从代码安全审查、自动化漏洞扫描、权限控制与访问管理、员工安全意识培训等四个关键维度加强防护。其中&#xff0c;代码安全审查是防止漏洞渗透的第一道防线。企业应将代码安全审查纳入CI/CD流程&#xff0c;实施静态代码分析和依赖包检查机…...

Text models —— BERT,RoBERTa, BERTweet,LLama

BERT 什么是BERT&#xff1f; BERT&#xff0c;全称Bidirectional Encoder Representations from Transformers&#xff0c;BERT是基于Transformer的Encoder&#xff08;编码器&#xff09;结构得来的&#xff0c;因此核心与Transformer一致&#xff0c;都是注意力机制。这种…...

CodeBuddy初探

回顾Trae 上一篇博客Trae IDE和VSCode Trae插件初探-CSDN博客&#xff0c;我们进行了TraeIDE和Trae插件初探&#xff0c;给了Trae这样一个任务&#xff1a; 生成一个to do list清单web页面&#xff0c;采用vue实现&#xff0c;可以在页面上进行todolist进行增删改查。 Trae的…...

spark数据处理练习题详解【上】

1. (单选题) scala中属于序列的可变的集合&#xff0c;可以添加&#xff0c;删除元素的是&#xff08;&#xff09; A.Array B.List C.Tuple D.ListBuffer 答案及解析&#xff1a;D 在Scala中&#xff0c;属于序列的可变集合&#xff0c;可以添加和删除元素的是&#xff…...

sparkSQL读入csv文件写入mysql(2)

&#xff08;二&#xff09;创建数据库和表 接下来&#xff0c;我们去创建一个新的数据库&#xff0c;数据表&#xff0c;并插入一条数据。 -- 创建数据库 CREATE DATABASE spark; -- 使用数据库 USE spark;-- 创建表 create table person(id int, name char(20), age int);-- …...

产品周围的几面墙

不能把排序&#xff0c;当单选题做。 2025年的杭州咖啡馆&#xff0c;味道最浓的不是咖啡&#xff0c;是聊各种项目和创业的卷味。 在过去几年&#xff0c;聊项目的也不少&#xff0c;那时候带着更加浓烈的自信和松弛感&#xff0c;不过今年略带几分忐忑和试探的口吻。 看到网…...

【锂电池剩余寿命预测】LSTM长短期记忆神经网络锂电池剩余寿命预测(Pytorch完整源码和数据)

目录 效果一览程序获取程序内容代码分享效果一览 程序获取 获取方式一:文章顶部资源处直接下载:...

螺旋矩阵--LeetCode

题目 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a;[1,2,3,6,9,8,7,4,5]示例 2&#xff1a; 输入&#xff1a;matrix [[…...

湖北理元理律师事务所:债务管理的社会价值探索

债务问题从来不是孤立的经济事件&#xff0c;其背后牵涉家庭稳定、社会信用体系乃至区域经济发展。湖北理元理律师事务所通过五年服务数据发现&#xff1a;科学债务规划可使单个家庭挽回约23%的可支配收入&#xff0c;间接降低离婚率、心理健康问题发生率等社会成本。 债务优化…...

知识图谱(KG)与大语言模型(LLM)

知识图谱&#xff08;KG&#xff09;以其结构化的知识表示和推理能力&#xff0c;为大语言模型&#xff08;LLM&#xff09;的“幻觉”、知识更新滞后和可解释性不足等问题提供了有力的解决方案。反过来&#xff0c;LLM的强大文本理解和生成能力也为KG的构建、补全、查询和应用…...

LLM大语言模型系列1-token

一&#xff0c;什么是token 1&#xff0c;什么是token&#xff1a; 参考&#xff1a;https://en.wikipedia.org/wiki/Token https://en.wikipedia.org/wiki/Lexical_analysis#Token 我们有很多描述token的解释&#xff0c;建议是汇总在一起进行综合理解&#xff1a; 1️⃣To…...

数据清洗-案例

四&#xff09;实现代码 在之前的项目的基础之上&#xff0c;重写去写一个包&#xff0c;并创建两个类&#xff1a;WebLogMapper和WebLogDriver类。 &#xff08;1&#xff09;编写WebLogMapper类 package com.root.mapreduce.weblog; import java.io.IOException; import…...

项目的部署发布和访问的流程

首先打包项目&#xff1a; npm run build 打包后的文件会生成在dist文件夹中&#xff0c;将dist文件夹需要放到服务器里面&#xff0c;意味着服务有dist静态资源&#xff08;index.html&#xff0c;css/&#xff0c;js/&#xff0c;img/&#xff09; 用户在浏览器输入域名&am…...

人工智能、机器学习、深度学习定义与联系

人工智能、机器学习、深度学习定义与联系目录 一、人工智能&#xff08;Artificial Intelligence, AI&#xff09;1、定义2、特征&#xff1a;3、关键阶段的概述&#xff1a;1. 萌芽期&#xff08;1940s–1950s&#xff09;&#xff1a;理论奠基2. 形成期&#xff08;1950s–19…...

Gartner《如何将生成式人工智能(GenAI)集成到应用架构》学习心得

针对软件架构师、技术专业人士如何更好的把 GenAI 如何融入解决方案,提升用户体验、生产力并带来差异化成果的趋势,Gartner发布了《Integrating GenAI Into Your Application Architecture》研究报告。 报告首先介绍了 GenAI 的发展背景,指出其已成为主流趋势,大型语言模型…...

vscode中Debug c++

在vscode中Debug ros c程序 1 在Debug模式下编译 如果用命令行catkin_make&#xff0c;在输入catkin_make时加上一个参数&#xff1a; catkin_make -DCMAKE_BUILD_TYPEDebug 或者直接修改CMakelist.txt&#xff0c;添加以下代码&#xff1a; SET(CMAKE_BUILD_TYPE "D…...

c++从入门到精通(六)--特殊工具与技术-完结篇

特殊工具与技术-完结篇 控制内存分配 重载new和delete&#xff1a; ​ 如果应用程序希望控制内存分配的过程&#xff0c;则它们需要定义自己的operator new函数和operator delete函数。当自定义了全局的operator new函数和operator delete函数后&#xff0c;我们就担负起了控…...

原型链的详细解释及使用场景

一、原型链的概念 原型链是JavaScript实现继承和属性共享的核心机制。每个对象都有一个内部属性[[Prototype]]&#xff08;可通过proto访问&#xff09;&#xff0c;指向其原型对象。当访问对象的属性时&#xff0c;若对象自身不存在该属性&#xff0c;则会沿着原型链向上查找…...

OpenCL C C++核心对象与属性对比

基础对象对应关系 OpenCL C 对象OpenCL C 对应类型创建函数示例cl::Platformcl_platform_idclGetPlatformIDs(1, &platform, NULL)cl::Devicecl_device_idclGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device, NULL)cl::Contextcl_contextclCreateContext(NULL,…...

Azure 机器学习初学者指南

Azure 机器学习初学者指南 在我们的初学者指南中探索Azure机器学习&#xff0c;了解如何设置、部署模型以及在Azure生态系统中使用AutoML & ML Studio。Azure 机器学习 &#xff08;Azure ML&#xff09; 是一项全面的云服务&#xff0c;专为机器学习项目生命周期而设计&am…...

一文读懂----Docker 常用命令

Docker 是一个强大的容器化平台&#xff0c;广泛用于开发、测试和生产环境。通过 Docker 命令行工具&#xff08;CLI&#xff09;&#xff0c;我们可以轻松管理容器、镜像、网络和卷等资源。本文将详细介绍 Docker 的常用命令&#xff0c;带你熟练掌握 Docker 的核心操作命令。…...

React 19 中的useRef得到了进一步加强。

文章目录 前言一 useRef 的核心原理1.1 为什么需要 useRef&#xff1f;1.2 基本语法 二、React 19 中 useRef 的常见用法2.1 访问 DOM 元素2.2 保存跨渲染的数据 三、React 19 中的改进ref 作为一个属性案例演示(触发子组件焦点事件) 注意 总结 前言 在 React 的世界里&#x…...

报错System.BadImageFormatException:“试图加载格式不正确的程序。 (异常来自 HRESULT:0x8007000B)”

this.hWindowControl_Player new HalconDotNet.HWindowControl();报错System.BadImageFormatException:“试图加载格式不正确的程序。 (异常来自 HRESULT:0x8007000B)” System.BadImageFormatException 错误通常是由于平台架构不匹配导致的。它意味着你正在尝试在一个平台上加…...

【图像处理基石】OpenCV中都有哪些图像增强的工具?

OpenCV 图像增强工具系统性介绍 OpenCV 提供了丰富的图像增强工具&#xff0c;主要分为以下几类&#xff1a; 亮度与对比度调整 线性变换&#xff08;亮度/对比度调整&#xff09;直方图均衡化自适应直方图均衡化&#xff08;CLAHE&#xff09; 滤波与平滑 高斯滤波中值滤波双…...

Nordic 的RTC(Real-time counter)的介绍

目录 概述 1 RTC&#xff08;Real-time counter&#xff09;介绍 1.1 框架结构 1.2 时钟源 1.3 分辨率与溢出和precaler 2 寄存器功能介绍 2.1 计数寄存器 2.2 事件控制功能 2.3 比较功能 2.4 读取COUNTER寄存器 概述 本文主要介绍Nordic 的RTC&#xff08;Real-time…...

【数据结构】2-2-2 顺序表的插入删除查找

数据结构知识点合集 知识点 顺序表的插入 ListInsert(&L,i,e)&#xff1a;插入操作。在表L中的第i个位置上插入指定元素e。 /*在顺序表L的第i个位置插入元素e*/ bool ListInsert(SqList &L,int i,int e) {/*判断i的范围是否有效*/if(i<0||i>L.length)return fals…...

【免杀】C2免杀技术(五)动态API

一、什么是动态API 在C2免杀领域中&#xff0c;“动态API” 主要指的是绕过静态检测的一种技术手段&#xff0c;其本质是运行时动态解析和调用Windows API函数&#xff0c;而不是在程序编译阶段就明确引用这些API。这种方式可以有效躲避静态分析工具和杀软的签名识别。 为什么…...

77.数据大小端赋值的差异与联系

上述赋值a定义为大端模式 a[7] a[6] a[5] a[4] a[3] a[2] a[1] a[0] 上述赋值b定义为小端模式 a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] 因为5的二进制数…...

GO语言语法---switch语句

文章目录 基本语法1. 特点1.1 不需要break1.2 表达式可以是任何类型1.3 省略比较表达式1.4 多值匹配1.5 类型switch1.6 case穿透1.7 switch后直接声明变量1.7.1 基本语法1.7.2 带比较表达式1.7.3 不带比较表达式1.7.4 结合类型判断 1.8 switch后的表达式必须与case语句中的表达…...

PH热榜 | 2025-05-16

1. Tolt 标语&#xff1a;专为SaaS初创公司打造的一体化联盟营销软件 介绍&#xff1a;Tolt帮助SaaS初创公司启动和发展联盟计划。它提供自动化的支付、欺诈保护、与多种平台的无缝集成&#xff08;包括Stripe、Paddle和Chargebee&#xff09;&#xff0c;还有一个品牌化的联…...

Java正则表达式:从基础到高级应用全解析

Java正则表达式应用与知识点详解 一、正则表达式基础概念 正则表达式(Regular Expression)是通过特定语法规则描述字符串模式的工具&#xff0c;常用于&#xff1a; 数据格式验证文本搜索与替换字符串分割模式匹配提取 Java通过java.util.regex包提供支持&#xff0c;核心类…...

iOS 初识RunLoop

iOS 初识RunLoop 文章目录 iOS 初识RunLoopRunLoop的概念RunLoop的功能RunLoop和线程的关系RunLoop的结构ModeObserverTimer 和 source小结 RunLoop的核心RunLoop的流程RunLoop的应用AutoreleasePool响应触控事件刷新界面常驻线程网络请求NSTimer 和 CADisplayLinkNSTimerGCDTi…...

备忘录模式

1.意图 备忘录模式是一种行为型设计模式&#xff0c;允许在不破坏封装的特性前提&#xff0c;获取并保存一个对象的内部状态&#xff0c;后续需要时恢复该状态。核心是将对象的状态存储在一个独立的备忘录对象中&#xff0c;并在需要时恢复。 2.模式类型 行为型对象设计模式 …...

UCOS 嵌入式操作系统

UCOS 嵌入式操作系统是一款在嵌入式领域应用广泛且具有重要地位的实时操作系统&#xff0c;以下是对它的详细介绍。 发展历程 初始版本诞生&#xff1a;UCOS 最早由美国嵌入式系统专家 Jean J. Labrosse 于 1991 年开始开发。当时他在项目中需要一个合适的实时操作系统&#…...

redis读写一致问题

title: redis读写一致问题 date: 2025-05-18 11:11:31 tags: redis categories: redis的问题方案 Redis读写一致问题 条件: 数据库此时的数据为10,redis此时的数据也为10 业务流程: 操作数据库使得数据库的数据为20&#xff0c;删除redis里面的数据保证读写一致 先删缓存…...

Redis实现分布式锁的进阶版:Redisson实战指南

一、为什么选择Redisson&#xff1f; 在上一篇文章中&#xff0c;我们通过Redis原生命令实现了分布式锁。但在实际生产环境中&#xff0c;这样的基础方案存在三大痛点&#xff1a; 锁续期难题&#xff1a;业务操作超时导致锁提前释放不可重入限制&#xff1a;同一线程无法重复…...

标准库、HAl库和LL库(PC13初始化)

标准库 (Standard Peripheral Library) c #include "stm32f10x.h"void GPIO_Init_PC13(void) {GPIO_InitTypeDef GPIO_InitStruct;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);GPIO_InitStruct.GPIO_Pin GPIO_Pin_13;GPIO_InitStruct.GPIO_Mode GPIO_…...

第二章:安卓端启动流程详解与疑难杂症调试手册

想让一个安卓项目跑起来&#xff0c;从表面看无非就是&#xff1a;双击打开、连接真机、点击运行。 但是到了互动娱乐组件项目里&#xff0c;事情就变成了&#xff1a;点击运行→等待→黑屏→白屏→强制退出→LogCat爆炸→你怀疑人生。 本章就来系统性解决几个问题&#xff1…...