Linux 进程信号详解
进程信号
信号是进程之间事件异步通知的一种方式,属于软中断。
kill -l //查看不同信号代表的事件
执行kill -l 可以看到共有62种信号,其中:
0-31号信号为非可靠信号(这部分信号借鉴于UNIX系统的信号);
34-64号信号为可靠信号(linux自己扩充的信号)。
· 每个信号都有一个编号和一个宏定义名称,这些宏定义可以在signal.h中找到,例如其中有定 义 #define SIGINT 2
· 编号34以上的是实时信号,本文只讨论编号34以下的信号,不讨论实时信号。这些信号各自在什么条件下产生,默认的处理动作是什么,在signal(7)中都有详细说明: man 7 signal
信号的产生
硬件产生:
1.ctrl+c :2号信号 SIGINT(键盘当中按下ctrl+c结束一个进程的时候,其实是进程收到了2号信号。2号信号导致了进程的退出。 )
2.ctrl+z :20号信号 SIGTSTP ,停止一个进程
3.ctrl+| :3号信号 SIGQUIT 退出一个进程
4.kill命令向进程发送信号:
kill -[信号值] [pid]
软件产生:
· kill函数:#include<signal.h> int kill(pid_t pid,int sig);
pid:进程号,给哪个进程发就填这个进程的进程号
sig:要发送的信号的值
· raise函数:int raise(int sig);
谁调用给谁发信号
sig:要发送的信号值
该函数的实现实际时调用kill函数
int raise(int sig){ return kill(getpid(),sig); }
kill -[num] [pid] //可以给进程发信号
信号的处理
可选的处理动作有以下三种:
1. 忽略此信号。
2. 执行该信号的默认处理动作。
3. 提供一个信号处理函数,要求内核在处理该信号时切换到用户态执行这个处理函数,这种方式称为捕捉(Catch)一个信号。
· 实际执行信号的处理动作称为信号递达(Delivery)
· 信号从产生到递达之间的状态,称为信号未决(Pending)。· 进程可以选择阻塞 (Block )某个信号。
· 被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作.
·注意,阻塞和忽略是不同的,只要信号被阻塞就不会递达,而忽略是在递达之后可选的一种处理动作。
信号的处理时机:分两种情况
普通情况:所谓的普通情况就是指 信号没有被阻塞,直接产生,记录未决信息后,再进行处理,在这种情况下,信号是不会被立即递达的,也就无法立即处理,需要等待合适的时机
特殊情况:当信号被 阻塞 后,信号 产生 时,记录未决信息,此时信号被阻塞了,也不会进行处理当阻塞解除后,信号会被立即递达,此时信号会被立即处理
信号的产生是 异步 的
当信号产生时,进程可能在处理更重要的事,此时贸然处理信号显然不够明智,因此信号在 产生 后,需要等进程将 更重要 的事忙完后(合适的时机),才进行 处理。
合适的时机:进程从 内核态 返回 用户态 时,会在操作系统的指导下,对信号进行检测及处理
至于处理动作,分为:默认动作、忽略、用户自定义
用户态与内核态
概念:
用户态:执行用户所写的代码时,就属于 用户态
内核态:执行操作系统的代码时,就属于 内核态
谈谈进程地址空间 :
- 进程地址空间 是虚拟的,依靠 页表+
MMU
机制 与真实的地址空间建立映射关系- 每个进程都有自己的 进程地址空间,不同 进程地址空间 中地址可能冲突,但实际上地址是独立的
- 进程地址空间 可以让进程以统一的视角看待自己的代码和数据
在 进程地址空间 中,存在 1 GB
的 内核空间,每个进程都有,而这 1 GB
的空间中存储的就是 操作系统 相关 代码 和 数据,并且这块区域采用 内核级页表 与 真实地址空间 进行映射 。
区分用户态和内核态的目的:
- 内核空间中存储的可是操作系统的代码和数据,权限非常高,绝不允许随便一个进程对其造成影响
- 区域的合理划分也是为了更好的进行管理
所谓的 执行操作系统的代码及系统调用,就是在使用这 1 GB
的内核空间
当我们执行诸如 open
这类的系统调用时,会跑到内核空间中调用对应的函数而跑到内核空间就是用户态切换为内核态了。
如何实现的呢?
在 CPU
中,存在一个 CR3
寄存器,这个 寄存器 的作用就是用来表征当前处于 用户态 还是 内核态
- 当寄存器中的值为
3
时:表示正在执行用户的代码,也就是处于 用户态- 当寄存器中的值为
0
时:表示正在执行操作系统的代码,也就是处于 内核态
· 所有进程的用户空间 [0, 3] GB 是不一样的,并且每个进程都要有自己的 用户级页表 进行不同的映射
· 所有进程的内核空间 [3, 4] GB 是一样的,每个进程都可以看到同一张内核级页表,从而进行统一的映射,看到同一个 操作系统
· 操作系统运行 的本质其实就是在该进程的 内核空间内运行的(最终映射的都是同一块区域)
· 系统调用 的本质其实就是在调用库中对应的方法后,通过内核空间中的地址进行跳转调用
· 操作系统的本质
- 操作系统也是软件,并且是一个死循环式等待指令的软件
- 存在一个硬件:操作系统时钟硬件,每隔一段时间向操作系统发送时钟中断
· 进程被调度,就意味着它的时间片到了,操作系统会通过时钟中断,检测到是哪一个进程的时间片到了,然后通过系统调用函数 schedule() 保存进程的上下文数据,然后选择合适的进程去运行
信号的处理过程
情况1:信号被阻塞,信号产生/未产生
信号都被阻塞了,也就不需要处理信号,此时不用管,直接切回 用户态 就行了
情况2:当前信号的执行动作为 默认
大多数信号的默认执行动作都是 终止 进程,此时只需要把对应的进程干掉,然后切回 用户态 就行了
情况3:当前信号的执行动作为 忽略
当信号执行动作为 忽略 时,不做出任何动作,直接返回 用户态
情况4:当前信号的执行动作为 用户自定义
这种情况就比较麻烦了,用户自定义的动作位于 用户态 中,也就是说,需要先切回 用户态,把动作完成了,重新坠入 内核态,最后才能带着进程的上下文相关数据,返回 用户态
1.在 内核态 中,也可以直接执行 自定义动作,为什么还要切回 用户态 执行自定义动作?
· 因为在 内核态 可以访问操作系统的代码和数据,自定义动作 可能干出危害操作系统的事
在 用户态 中可以减少影响,并且可以做到溯源
2.为什么不在执行完 自定义动作 直接后返回进程?· 因为 自定义动作 和 待返回的进程 属于不同的堆栈,是无法返回的
并且进程的上下文数据还在内核态中,所以需要先坠入内核态,才能正确返回用户态
信号捕捉
概念:如果信号的执行动作为用户自定义动作,当信号递达时调用用户自定义动作,这一动作称为信号捕捉。(用户自定义动作 是位于 用户空间 中的)
当 内核态 中任务完成,准备返回 用户态 时,检测到信号 递达,并且此时为 用户自定义动作,需要先切入 用户态 ,完成 用户自定义动作 的执行;因为 用户自定义动作 和 待返回的函数 属于不同的 堆栈 空间,它们之间也不存在 调用与被调用 的关系,是两个 独立的执行流,需要先坠入 内核态 (通过 sigreturn() 坠入),再返回 用户态 (通过 sys_sigreturn() 返回)
signal
#include <signal.h>typedef void (*__sighandler_t) (int);
__sighandler_t signal(int signo, __sighandler_t handler);
参数:
第一个参数为信号名
第二个参数为:
- SIG_IGN,内核忽略该信号,除了两个不能忽略;
- SIG_DFL,采用系统默认方式处理该信号;
- 函数指针,按照用户的方式处理该信号;
返回值:
- 如果出错,返回SIG_ERR;
- 如果成功,返回上一个处理程序的指针;
下面是一个简单的信号捕捉:
void hander(int sig)
{cout << "get a sig: " << sig << endl;
}int main(){ // 对信号的自定义捕捉,我们只要捕捉一次,后续一直有效// 2 SIGINT默认是什么动作呢?终止进程// 2 SIGINT是什么呢?ctrl+c --- 给目标进程发送2号信号,SIGINT默认是什么动作呢?终止进程signal(2, hander);while (true){cout << "hello bit,pid:" << getpid() << endl;sleep(1);}}
sigaction
sigaction
也可以 用户自定义动作,比 signal
功能更丰富
#include <signal.h>int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);struct sigaction
{void (*sa_handler)(int); //自定义动作void (*sa_sigaction)(int, siginfo_t *, void *); //实时信号相关,不用管sigset_t sa_mask; //待屏蔽的信号集int sa_flags; //一些选项,一般设为 0void (*sa_restorer)(void); //实时信号相关,不用管
};
参数:
参数1:待操作的信号
参数2:
sigaction
结构体,具体成员如上所示参数3:保存修改前进程的
sigaction
结构体信息
返回值:成功返回
0
,失败返回-1
并将错误码设置
这个函数的主要看点是 sigaction
结构体,其中部分字段不需要管,因为那些是与 实时信号 相关的,我们这里不讨论,重点可以看看 sa_mask
字段
sa_mask
:当信号在执行 用户自定义动作 时,可以将部分信号进行屏蔽,直到 用户自定义动作 执行完成
也就是说,我们可以提前设置一批 待阻塞 的 屏蔽信号集,当执行 signum
中的 用户自定义动作 时,这些 屏蔽信号集 中的 信号 将会被 屏蔽(避免干扰 用户自定义动作 的执行),直到 用户自定义动作 执行完成
#include <iostream>
#include <cassert>
#include <cstring>
#include <signal.h>
#include <unistd.h>using namespace std;static void DisplayPending(const sigset_t pending)
{// 打印 pending 表cout << "当前进程的 pending 表为: ";int i = 1;while (i < 32){if (sigismember(&pending, i))cout << "1";elsecout << "0";i++;}cout << endl;
}static void handler(int signo)
{cout << signo << " 号信号确实递达了" << endl;// 最终不退出进程int n = 10;while (n--){// 获取进程的 未决信号集sigset_t pending;sigemptyset(&pending);int ret = sigpending(&pending);assert(ret == 0);(void)ret; // 欺骗编译器,避免 release 模式中出错DisplayPending(pending);sleep(1);}
}int main()
{cout << "当前进程: " << getpid() << endl;//使用 sigaction 函数struct sigaction act, oldact;//初始化结构体memset(&act, 0, sizeof(act));memset(&oldact, 0, sizeof(oldact));//初始化 自定义动作act.sa_handler = handler;//初始化 屏蔽信号集sigaddset(&act.sa_mask, 3);sigaddset(&act.sa_mask, 4);sigaddset(&act.sa_mask, 5);//给 2号 信号注册自定义动作sigaction(2, &act, &oldact);// 死循环while (true);return 0;
}
当 2
号信号的循环结束(10
秒),3、4、5
信号的 阻塞 状态解除,立即被 递达,进程就被干掉了
注意: 屏蔽信号集 sa_mask
中已屏蔽的信号,在 用户自定义动作 执行完成后,会自动解除 阻塞 状态
· 信号产生阶段:有四种产生方式,包括 键盘键入、系统调用、软件条件、硬件异常
· 信号保存阶段:内核中存在三张表,
blcok
表、pending
表以及handler
表,信号在产生之后,存储在pending
表中· 信号处理阶段:信号在 内核态 切换回 用户态 时,才会被处理
可重入函数
可以被重复进入的函数称为 可重入函数
我们学过的函数中,90%
都是不可重入的,函数是否可重入是一个特性,而非缺点,需要正确看待
不可重入的条件:
- 调用了内存管理相关函数
- 调用了标准
I/O
库函数,因为其中很多实现都以不可重入的方式使用数据结构
相关文章:
Linux 进程信号详解
进程信号 信号是进程之间事件异步通知的一种方式,属于软中断。 kill -l //查看不同信号代表的事件 执行kill -l 可以看到共有62种信号,其中: 0-31号信号为非可靠信号(这部分信号借鉴于UNIX系统的信号);…...
MCP 应用案例-网络设备批量管理
案例背景 需求痛点 企业需管理数百台跨地域网络设备(交换机/路由器),传统方式存在: 人工SSH登录效率低脚本维护成本高(不同厂商CLI语法差异)状态监控依赖独立监控系统 解决方案 通过MCP协议构建智能网络…...
进程程序替换
fork() 之后,⽗⼦各⾃执⾏⽗进程代码的⼀部分如果⼦进程就想执⾏⼀个全新的程序呢?进程的程序 替换来完成这个功能! 程序替换是通过特定的接⼝,加载磁盘上的⼀个全新的程序(代码和数据),加载到调⽤进程的地址空间中!…...
6.7 ChatGPT自动生成定时任务脚本:Python与Cron双方案实战指南
ChatGPT自动生成定时任务脚本:Python与Cron双方案实战指南 关键词:定时任务调度, ChatGPT 代码生成, Cron 脚本开发, Python 调度器, 自动化更新系统 6.3 使用 ChatGPT 生成 Cron 调度脚本 在 GitHub Sentinel 的定期更新功能中,定时任务调度是核心模块。本节演示如何通过…...
废物九重境弱者学JS第十四天--构造函数以及常用的方法
目录 JavaScript 进阶 - 第2天 深入对象 构造函数 实例成员 静态成员 内置构造函数 Object Array 包装类型 String Number 案例 JavaScript 进阶 - 第2天 了解面向对象编程的基础概念及构造函数的作用,体会 JavaScript 一切皆对象的语言特征,…...
机器学习+深度学习
文章目录 一、机器学习(一)机器学习概念(二)机器学习基本流程(三)机器学习应用场景二、机器学习的常见工具与相关库(一)Python 机器学习库(二)数据处理库(三)可视化库三、聚类算法思想与模型搭建过程(一)K - Means 聚类算法(二)DBSCAN 聚类算法四、分类算法思想…...
docker基本使用命令
一、镜像 1、拉取镜像 docker pull busybox docker pull nginx:1.26-alpine 2、查看本地镜像 [rootRocky-1 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest 4e1b6bae1e48 18 hours ago 192MB busybox lates…...
相机模型--CMOS和CCD的区别
1--CMOS和CCD的工作原理 CCD(Charge Coupled Device,电荷耦合器件): 1. 图像通过光电效应在感光单元中转化为电荷; 2. 每个像素上的电荷被依次“耦合”并传输到芯片的角落,通过一个或几个模拟输出放大器输…...
触发器(详解)
一:MySQL触发器 MySQL数据库中触发器是一个特殊的存储过程。 不同的是执行存储过程要使用 CALL 语句来调用,而触发器的执行不需要使用 CALL 语句来调用,也不需要手工启动,只要一个预定义的事件发生就会被 MySQL自动调用。 引发…...
Vue 3 中将 ref 创建的响应式对象数据转换为普通(非响应式)的数据
Vue 3 中使用 ref 创建的响应式对象数据转换为普通(非响应式)的数据,有以下几种方法: 1. 访问 .value 属性: 这是最直接、最常见的方法。 由于 ref 对象的值存储在其 .value 属性中,直接访问该属性即可获得普通数据。…...
Vue基础(6)_键盘事件
普通键盘事件 键盘事件常用的有两个:keydown、keyup。 举例: <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><script type"text/javascript" src"../js/vue.js"&…...
Kubernetes控制平面组件:高可用 APIServer
云原生学习路线导航页(持续更新中) kubernetes学习系列快捷链接 Kubernetes架构原则和对象设计(一)Kubernetes架构原则和对象设计(二)Kubernetes架构原则和对象设计(三)Kubernetes控…...
这个是我的qss按钮样式 和之前的// 应用全局样式表 QString style = R“(是会冲突吗,导致我的按钮背景颜色是黑色,我该怎么修改
/* 样式 A */ *[style-type="A"] { background-color:#cfd1d4; border: none; border-radius: 50%; /* 圆形边框 */ padding: 7px 14px; } *[style-type="A"]:hover { background-color: #45a049; }这个是我的qss按钮样式 和之前的// 应用全局样式表 QStri…...
Kubernetes控制平面组件:API Server详解(二)
云原生学习路线导航页(持续更新中) kubernetes学习系列快捷链接 Kubernetes架构原则和对象设计(一)Kubernetes架构原则和对象设计(二)Kubernetes架构原则和对象设计(三)Kubernetes控…...
人工智能在智慧农业中的应用:从田间到餐桌的变革
农业是人类社会的基石,随着全球人口的增长和资源的日益紧张,传统农业面临着巨大的挑战。近年来,人工智能(AI)技术的快速发展为农业带来了新的机遇。智慧农业通过将AI技术与农业生产相结合,实现了从田间种植…...
多人3D游戏完整实现方案
以下是一份完整的代码实现方案,涵盖架构设计、核心模块实现和部署流程。我们以 多人3D游戏 为例,结合之前讨论的Nano服务端框架和Unity客户端: 技术栈 模块技术选型服务端Golang + Nano框架 + MongoDB客户端Unity 2022 + C# + Mirror Networking通信协议Protobuf + WebSock…...
FFUF指南
ffuf 的核心功能: 目录/文件发现: 通过暴力破解(使用字典)探测目标网站的隐藏目录或文件,例如: ffuf -w /path/to/wordlist.txt -u http://target.com/FUZZ 子域名枚举: 通过模糊测试发现目标…...
详细的PyCharm安装教程
详细的PyCharm安装教程 安装前准备 确认系统要求: Windows:Microsoft Windows 10 1809 64位或更高版本,Windows Server 2019 64位或更高版本。 macOS:12.0或更高版本。 Linux:满足以下要求的两个最新版本的Ubuntu LTS或…...
FPGA IO引脚 K7-认知4
UG475来知道bank, GTX, Pin数量, Package, Pinout 时钟 SRCC(Single-Region Clock Capable I/O)和MRCC(Multi-Region Clock Capable I/O)是专用的时钟输入/输出引脚。 如 2.DQS...
C++——异常
1. C语言错误处理机制 我们在曾经介绍过C语言下的错误码。错误码我们过去经常见到,错误码通常是指errno变量中的值,它表示特定操作(如系统调用或库函数)发生错误的原因。errno是一个全局变量,当出现错误时会自动将错误…...
vue3 中 iframe 多页面切换导致资源刷新的问题解决
最近发现一个问题,我在使用 websocket 的时候,在主页面进行了 websocket 连接了之后,再使用 iframe 打开子页面的时候,通常会触发页面刷新,这样就导致 WebSocket 断开,这是因为切换 src 会重新加载 iframe …...
php多种方法实现xss过滤
1. 使用 htmlspecialchars() 函数 htmlspecialchars() 是一个PHP内置函数,用于将特殊字符转换为HTML实体,从而防止浏览器将其解释为HTML或脚本代码。 <?phpfunction sanitizeInput($input) {// 将特殊字符转换为HTML实体return htmlspecialchars($…...
蓝桥杯练习题2
动态规划 动态规划三大题型:计数问题、最值问题、存在性问题; 【最小权值】-- 最值问题 【题目分析】 import java.util.Arrays; Arrays类中的一个方法:Arrays.fill(int[] m,int n) //给 int 类型(或者char类型/Long类型...)的数组全部空间…...
Python遥感开发之Hurst指数的实现
Python遥感开发之Hurst指数的实现 主要讲解Python实现Hurst指数,实现遥感下的Hurst指数,对Hurst指数进行分类,以及结合slope指数实现对未来变化趋势的分析。 文章目录 Python遥感开发之Hurst指数的实现0 什么是Hurst指数1 Python实现Hurst指…...
opencv 给图片和视频添加水印
给图片和视频添加水印 1 给图片添加水印2 给视频添加水印 1 给图片添加水印 代码如下: 添加水印 imgcv2.imread(r../15day4.10/src/xiaoren.png) img2cv2.imread(r../15day4.10/src/bg.png) h,w,cimg.shapeRIO_img2img2[100:100h,200:200w]img3cv2.cvtColor(img,…...
国网B接口协议图像数据上报通知接口流程详解以及上报失败原因(电网B接口)
文章目录 一、B接口协议图像数据上报通知接口介绍B.13.1 接口描述B.13.2 接口流程B.13.3 接口参数B.13.3.1 SIP头字段B.13.3.2 SIP响应码B.13.3.3 XML Schema参数定义 B.13.4 消息示例B.13.4.1 图像数据上报请求B.13.4.2 图像数据上报响应 二、B接口图像数据上报通知失败常见问…...
Redis(持久化)
目录 一 Redis持久化的方式 1. RDB(Redis Database) 2. AOF(Append Only File) 二 对比RDB/AOF 为什么要持久化 Redis是跑在内存上的,但内存上的数据是临时的,Redis服务挂了,数据也就丢失了,所以为了解决上述问题,R…...
Linux系统中的网络管理
1.RHEL9版本中,使用nm进行网络配置,ifcfg不再是网络配置文件的主存储,样式仍然可用,但它不再是NetworkManger存储新网络配置文件的默认位置,RHEL以key-file格式在etc/NetworkManger/system-connections/中存储新的网络…...
【深度学习—李宏毅教程笔记】Transformer
目录 一、序列到序列(Seq2Seq)模型 1、Seq2Seq基本原理 2、Seq2Seq模型的应用 3、Seq2Seq模型还能做什么? 二、Encoder 三、Decoder 1、Decoder 的输入与输出 2、Decoder 的结构 3、Non-autoregressive Decoder 四、Encoder 和 De…...
关于UE5的抗锯齿和TAA
关于闪烁和不稳定现象的详细解释 当您关闭抗锯齿技术时,场景中会出现严重的闪烁和不稳定现象,尤其在有细节纹理和小物体的场景中。这种现象的技术原因如下: 像素采样问题 在3D渲染中,每个像素只能表示一个颜色值,但…...
交换网络基础
学习目标 掌握交换机的基本工作原理 掌握交换机的基本配置 交换机的基本工作原理 交换机是局域网(LAN)中实现数据高效转发的核心设备,工作在 数据链路层(OSI 模型第二层),其基本工作原理可概括为 “学习…...
AUTOSAR图解==>AUTOSAR_SWS_EFXLibrary
AUTOSAR 扩展定点数学函数库(EFX)分析 1. 概述 AUTOSAR (AUTomotive Open System ARchitecture) 是汽车电子控制单元(ECU)软件架构的开放标准。在AUTOSAR架构中,扩展定点数学函数库(Extended Fixed-point library, EFX)提供了一组优化的定点数学运算函数ÿ…...
六边形棋盘格(Hexagonal Grids)的坐标
1. 二位坐标转六边形棋盘的方式 1-1这是“波动式”的 这种就是把【方格子坐标】“左右各错开半个格子”做到的 具体来说有如下几种情况 具体到庙算平台上,是很巧妙的用一个4位整数,前两位为x、后两位为y来进行表示 附上计算距离的代码 def get_hex_di…...
李宏毅NLP-5-RNNTNeural TransducerMoChA
RNN Transducer(RNN-T) 循环神经对齐器(RNA,Recurrent Neural Aligner)对CTC解码器的改进,具体内容如下: “RNA”,全称 “Recurrent Neural Aligner”,引用来自 [Sak, et al., INTERSPEECH’17…...
GPT-SoVITS 使用指南
一、简介 TTS(Text-to-Speech,文本转语音):是一种将文字转换为自然语音的技术,通过算法生成人类可听的语音输出,广泛应用于语音助手、无障碍服务、导航系统等场景。类似的还有SVC(歌声转换&…...
洛谷的几道题
P1000 超级玛丽游戏 # P1000 超级玛丽游戏 ## 题目背景 本题是洛谷的试机题目,可以帮助了解洛谷的使用。 建议完成本题目后继续尝试 [P1001](/problem/P1001)、[P1008](/problem/P1008)。 另外强烈推荐[新用户必读帖](/discuss/show/241461)。 ## 题目描述 …...
利用yakit充实渗透字典
前言 在渗透侧测试结束,在我们的历史记录中会保存过程中的数据包。在其中有些特征,比如API、参数,可以活用于下次的渗透。 比如 fuzz变量,fuzz隐藏API…… 但是我们一个一个提取很麻烦,可以使用yakit的插件…...
精益数据分析(4/126):开启数据驱动的创业之旅
精益数据分析(4/126):开启数据驱动的创业之旅 在创业的浪潮中,我们都怀揣着梦想,渴望找到那条通往成功的道路。作为一名在创业和数据分析领域摸爬滚打多年的“老兵”,我深知其中的艰辛与挑战。今天&#x…...
机器学习误差图绘
机器学习误差图绘制 绘图类 # Define the ModelComparisonPlot class class ModelComparisonPlot:def __init__(self, model_name):self.model_name model_namedef plot_comparison(self, y_val, y_pred, mse, mae, r2):# Create a figure with two subplotsfig, axes plt.…...
企业级RAG选择难题:数据方案的关键博弈
企业级RAG选择难题:数据方案的关键博弈 向量数据库:高效但易失语境图数据库与知识图谱:关系网络的力量企业级RAG数据方案的最佳实践 智能时代,企业数据每日剧增。员工寻找答案的效率直接影响工作流程,StackOverflow调查…...
JNI 学习
1. JNI 不属于 C,而是 JDK 的 日志失效,可以 adb kill-server adb kill-serveradb start-server 使用 jni final和 private变量都能修改...
PyTorch :优化的张量库
PyTorch 是一个基于 Python 的开源机器学习框架,由 Facebook 的 AI 研究团队(现 Meta AI)于 2016 年推出。它专为深度学习设计,但也可用于传统的机器学习任务。PyTorch 的核心优势在于灵活性、动态计算图和易…...
DevOps 进阶指南:如何让工作流更丝滑?
DevOps 进阶指南:如何让工作流更丝滑? 引言 在 DevOps 世界里,我们追求的是高效、稳定、自动化。但现实总是充满挑战:代码部署失败、CI/CD 过程卡顿、环境不一致……这些痛点让开发和运维团队疲惫不堪。今天,我就来聊聊如何优化 DevOps 工作流,通过实战案例和代码示例,…...
BT-Basic函数之首字母XY
BT-Basic函数之首字母XY 文章目录 BT-Basic函数之首字母XYXxd__ commands Yyes X xd__ commands 当使用外部设备时,开发人员需要在测试计划中添加适当的命令来控制这些设备。下表显示了一个典型的命令序列。 典型的命令序列 NO命令描述1xdload将DLL加载到内存中…...
6. 话题通信 ---- 使用自定义msg,发布方和订阅方cpp,python文件编写
1)在功能包下新建msg目录,在msg目录下新建Person.msg,在Person.msg文件写入: string name uint16 age float64 height 2)修改配置文件 2.1) 功能包下package.xml文件修改 <build_depend>message_generation</build_depend><exec_depend…...
Fastdata极数:全球AR/VR行业发展趋势报告2025
科技的快速发展孕育了一个新的数字前沿领域,那就是虚拟宇宙,也就是我们谈论的元宇宙(Metaverse),虚拟宇宙最初构思于尼尔斯蒂芬森的科幻小说《雪崩》中,小说中虚拟宇宙由虚拟人物居住,并以数字方…...
背包 DP 详解
文章目录 背包DP01 背包完全背包多重背包二进制优化单调队列优化 小结 背包DP 背包 DP,说白了就是往一个背包里扔东西,求最后的最大价值是多少,一般分为了三种:01 背包、完全背包和多重背包。而 01 背包则是一切的基础。 01 背包…...
深入剖析 HashMap:内部结构与性能优化
深入剖析 HashMap:内部结构与性能优化 引言 HashMap 是 Java 集合框架中的核心类,广泛应用于数据存储和检索场景。本文将深入剖析其内部结构,包括数组、链表和红黑树的转换机制,帮助读者理解其工作原理和性能优化策略。 1. Hash…...
数据从辅存调入主存,页表中一定存在
在虚拟内存系统中,数据从辅存调入主存时,页表中一定存在对应的页表项,但页表项的「存在状态」会发生变化。以下是详细分析: 关键逻辑 页表的作用 页表是虚拟内存的核心数据结构,记录了虚拟地址到物理地址的映射关系…...
藏品馆管理系统
藏品馆管理系统 项目简介 这是一个基于 PHP 开发的藏品馆管理系统,实现了藏品管理、用户管理等功能。 藏品馆管理系统 系统架构 开发语言:PHP数据库:MySQL前端框架:BootstrapJavaScript 库:jQuery 目录结构 book/…...