穿越虚拟与现实:解密Linux进程的地址空间
在 Linux 操作系统中,每个进程都有独立的虚拟地址空间。虚拟地址空间是操作系统为每个进程提供的抽象内存模型,它使得每个进程都觉得自己拥有独立的内存,而不需要关心物理内存的具体布局。本文将深入探讨 Linux 进程的虚拟地址空间及其管理机制。
1. 虚拟地址空间的概念
虚拟地址空间(也可以叫进程地址空间)是每个进程能够访问的内存地址范围。操作系统通过内存管理单元(MMU,Memory Management Unit)将虚拟地址转换为物理地址,实现内存虚拟化。
虚拟地址空间本质上是一个结构体对象struct mmu_struct,用来管理每个进程的虚拟地址。
1.1 虚拟内存与物理内存的区别
虚拟内存是操作系统提供的一种抽象,允许每个进程认为自己拥有一个连续的内存区域。物理内存则是实际的硬件内存,是有限的,而虚拟内存的大小通常远大于物理内存。并且一个进程一个虚拟地址空间(一个task_struct, 一个虚拟地址空间)。
1.2 地址空间的布局
每个进程的虚拟地址空间通常分为几个区域,包括:
- 文本段(Text Segment): 存放可执行的机器代码,正文代码。
- 数据段(Data Segment): 存放已初始化的全局变量和静态变量。
- BSS段: 存放未初始化的全局变量和静态变量。
- 堆(Heap): 用于动态分配内存,程序运行时可以向堆中申请内存。
- 栈(Stack): 用于存储局部变量和函数调用时的返回地址。
下图中用户空间的数据,入堆、栈、初始化数据等拿到地址就可以直接访问。虚拟地址空间是操作系统为每个进程分配的逻辑地址范围,在内核中通过特定的数据结构(结构体)来管理这些地址范围及其映射关系。
1 #include <stdio.h>2 #include <unistd.h>3 #include <stdlib.h>4 5 int g_unval;6 int g_val = 100;7 8 int main(int argc, char *argv[], char *env[])9 {10 const char *str = "helloworld";11 printf("code addr: %p\n", main);12 printf("init global addr: %p\n", &g_val);13 printf("uninit global addr: %p\n", &g_unval);14 static int test = 10;15 char *heap_mem = (char*)malloc(10);16 char *heap_mem1 = (char*)malloc(10);17 char *heap_mem2 = (char*)malloc(10);18 char *heap_mem3 = (char*)malloc(10); 19 printf("heap addr: %p\n", heap_mem); //heap_mem(0), &heap_mem(1)20 printf("heap addr: %p\n", heap_mem1); //heap_mem(0), &heap_mem(1)21 printf("heap addr: %p\n", heap_mem2); //heap_mem(0), &heap_mem(1)22 printf("heap addr: %p\n", heap_mem3); //heap_mem(0), &heap_mem(1)23 24 printf("test static addr: %p\n", &test); //heap_mem(0), &heap_mem(1)25 printf("stack addr: %p\n", &heap_mem); //heap_mem(0), &heap_mem(1)26 printf("stack addr: %p\n", &heap_mem1); //heap_mem(0), &heap_mem(1)27 printf("stack addr: %p\n", &heap_mem2); //heap_mem(0), &heap_mem(1)28 printf("stack addr: %p\n", &heap_mem3); //heap_mem(0), &heap_mem(1)29 30 printf("read only string addr: %p\n", str);31 for(int i = 0 ;i < argc; i++)32 {33 printf("argv[%d]: %p\n", i, argv[i]);34 }35 for(int i = 0; env[i]; i++)36 {37 printf("env[%d]: %p\n", i, env[i]);38 }39 return 0;40 }
1.3 虚拟地址与物理地址映射
虚拟地址和物理地址通过页表进行映射。变量只是程序运行中的逻辑抽象,存储的是它们对应的内存地址。操作系统使用分页技术,将虚拟内存划分为小块(通常为4KB一页),并将这些虚拟页映射到物理内存中的页面。MMU 根据页表将虚拟地址转换为物理地址。下图中页表左侧记录进程的虚拟地址,右侧记录虚拟地址对应的物理地址。
页表的作用是将虚拟地址映射到物理地址,而不是直接存储变量。
一个进程,一个页表。
1.4 证明虚拟地址
下面的父子进程地址一样,如果是内存地址,那就是BUG, 所以它不是内存地址,它叫做虚拟地址。C/C++指针用到的地址都是虚拟地址。
子进程被创建时会共享父进程的虚拟地址空间,虚拟地址映射指向相同的物理地址。此时,父子进程对相同内存区域的访问是只读的。一旦任一进程尝试写入共享内存区域时,会触发“写时拷贝”(Copy-On-Write,COW)机制,为写入操作分配新的物理内存,从而实现进程间内存的独立性。
-
共享虚拟地址空间: 子进程创建时(例如通过
fork
系统调用),初始状态下会完全复制父进程的虚拟地址空间,但虚拟地址的映射指向相同的物理地址。这是一种内存优化机制,避免在进程创建时立即复制大量内存。 -
写时拷贝机制: 父子进程共享的物理内存区域在写入时触发写时拷贝,操作系统会分配新的物理内存块,将原内容复制到新内存块中,以确保每个进程的写入操作互不干扰。
-
读写行为区分: 在共享期间,读操作不会引发写时拷贝,只有写操作才会触发物理内存的复制,保证效率和独立性。
2. 虚拟地址与进程地址空间
2.1 是什么?
虚拟地址是操作系统为进程提供的一种逻辑地址,用于访问内存。它是程序编写和执行时所使用的地址,由操作系统和硬件(如内存管理单元 MMU)将其映射到实际的物理地址。
虚拟地址空间是操作系统为进程定义的一整个虚拟地址范围,是虚拟地址的集合。它表示进程可以使用的虚拟地址范围和布局。
进程地址空间是虚拟地址空间的一个实例,它表示某个特定进程在运行时可以使用的所有虚拟地址范围。它包含该进程的代码、数据、堆、栈等内存段。
2.2 程序加载为进程
程序加载为进程的过程主要涉及虚拟地址空间的分配、程序的加载以及虚拟地址到物理地址的映射。以下是详细的三个步骤解析:
(1)虚拟地址空间中申请同样大小的内存
-
概念:
当操作系统加载一个程序时,会在该进程的虚拟地址空间中为程序的各个部分(如代码段、数据段、BSS 段等)预留相应的地址范围。 -
细节:
- 这一步并不会实际分配物理内存,而是仅在虚拟地址空间中划分出程序运行所需的逻辑地址范围。
- 根据程序的二进制文件(如 ELF 格式)描述,操作系统会按照不同的段(代码段、数据段等)的大小和属性进行布局。
- 这些划分通常基于程序的逻辑需求,例如代码段是只读的,而数据段是可读写的。
(2)加载程序,申请物理空间
-
概念:
操作系统根据程序的实际需求,将程序的部分内容(如可执行代码)从磁盘加载到内存中,并为需要动态分配的区域(如堆)分配物理内存。 -
过程:
- 代码段和数据段: 操作系统从可执行文件中读取代码段和已初始化的数据段,将其内容加载到物理内存中。
- BSS 段: 未初始化的数据段不需要加载实际数据,而是直接在物理内存中申请相应大小的内存,并初始化为 0。
- 堆和栈: 堆和栈的内存区域通常在程序运行时动态分配。
-
按需加载:
为了优化性能,现代操作系统通常采用**按需加载(Lazy Loading)**策略:- 程序首次访问某个虚拟地址时,才将对应的物理内存分配到该地址。
- 这减少了程序启动时的内存消耗和加载时间。
(3)页表进行映射
-
概念:
页表是虚拟地址到物理地址映射的核心数据结构,操作系统通过页表建立虚拟地址与物理内存的对应关系。 -
过程:
- 建立映射: 在程序加载过程中,操作系统会根据虚拟地址空间的布局和已分配的物理内存,更新页表,记录虚拟地址与物理地址的对应关系。例如,代码段的虚拟地址
0x400000
可能映射到物理地址0x1A0000
。 - 按页管理: 虚拟地址空间被划分为多个固定大小的页(通常为 4KB),每个虚拟页对应一个物理页框(Page Frame)。
- 保护属性: 页表不仅负责映射,还记录地址的访问权限(如只读、可执行),以防止非法访问。
- TLB 缓存: 为加速地址转换,页表的部分内容会缓存在**TLB(Translation Lookaside Buffer)**中。
- 建立映射: 在程序加载过程中,操作系统会根据虚拟地址空间的布局和已分配的物理内存,更新页表,记录虚拟地址与物理地址的对应关系。例如,代码段的虚拟地址
-
写时拷贝(Copy-on-Write):
- 当多个进程共享某段内存时(如子进程继承父进程的虚拟地址空间),页表会标记为只读。
- 只有当某进程尝试写入时,操作系统才会触发写时拷贝机制,分配新的物理内存并更新页表。
完整过程总结
- 虚拟地址空间分配: 操作系统在虚拟地址空间中划分各个区域,预留程序所需的逻辑地址范围。
- 程序加载与物理内存分配: 将程序的代码段、数据段加载到物理内存中,并根据需要动态分配堆和栈的内存。
- 页表映射: 操作系统通过页表将虚拟地址与物理地址进行映射,并维护访问权限和动态调整。
图示:程序加载与映射过程
虚拟地址空间:
+----------------------+ <--- 栈区 (动态增长)
| Stack |
+----------------------+ <--- 堆区 (动态增长)
| Heap |
+----------------------+ <--- 数据段 (静态分配)
| Initialized Data |
+----------------------+ <--- BSS 段
| Uninitialized Data |
+----------------------+ <--- 代码段
| Code |
+----------------------+ <--- 虚拟地址空间起始物理内存:
+----------------------+
| 物理页框 X | <---> 虚拟地址页 A (代码段)
+----------------------+
| 物理页框 Y | <---> 虚拟地址页 B (数据段)
+----------------------+
| 物理页框 Z | <---> 虚拟地址页 C (堆区)
+----------------------+页表:
+----------------+----------------+
| 虚拟地址页 A | 物理页框 X |
| 虚拟地址页 B | 物理页框 Y |
| 虚拟地址页 C | 物理页框 Z |
+----------------+----------------+
通过这一系列操作,程序被加载为一个独立的进程,并能通过虚拟地址访问对应的物理内存,从而实现进程的高效运行和内存隔离。
2.3 为什么要有虚拟地址空间
(1)将地址从“无序”变“有序”
(2)地址转换过程中,也可以对你的地址和操作进行合法性判定,保护物理内存
(3)让内存管理和进程管理进行一定程度的解耦合
3. 进程相关信息之间的关系
在操作系统中,进程、PCB(进程控制块)、进程地址空间、内核数据结构、物理内存、虚拟内存、代码和数据等概念是紧密相互关联的,它们共同构成了操作系统管理和调度进程的基础。下面是这些概念之间的关系解析:
1. 进程(Process)
进程是操作系统管理的基本单位,是正在运行的程序的实例。一个进程通常包含以下内容:
- 程序代码: 要执行的机器指令。
- 数据: 程序执行过程中需要的数据(如全局变量、动态分配的内存等)。
- 状态信息: 如程序计数器、寄存器值等,表示进程当前的执行状态。
- 进程控制块(PCB): 进程的管理信息,操作系统用来管理进程的状态。
2. 进程控制块(PCB, Process Control Block)
进程控制块(PCB)是操作系统用来存储与进程相关的信息的内核数据结构。每个进程都对应一个PCB,主要包含:
- 进程ID、状态、优先级、程序计数器 等进程的基本信息。
- CPU寄存器的值,保存进程的上下文。
- 内存管理信息,例如虚拟地址空间的映射信息。
- 文件描述符、信号等信息,记录进程使用的文件资源和系统信号。
关系:
进程控制块(PCB)在操作系统中是进程的标识,它为操作系统提供了管理进程生命周期和调度的信息。每个进程有一个对应的PCB,操作系统通过PCB来追踪和管理进程。
3. 进程地址空间(Process Address Space)
进程地址空间是操作系统为每个进程创建的一个虚拟空间。它为进程提供了一个统一的、连续的地址空间,通常包括:
- 代码段(Text Segment): 存储可执行的程序代码。
- 数据段(Data Segment): 存储已初始化的全局变量、静态变量等。
- BSS段(BSS Segment): 存储未初始化的全局变量、静态变量等。
- 堆(Heap): 用于动态分配内存。
- 栈(Stack): 用于函数调用时存储局部变量和调用信息。
关系:
进程地址空间是进程的虚拟内存的映射,为程序提供一个统一的内存视图。操作系统通过虚拟内存管理将进程地址空间映射到物理内存上,而不必让程序直接与物理内存打交道。
4. 内核数据结构(Kernel Data Structures)
内核数据结构是操作系统在内核模式下用于管理和调度系统资源的数据结构。常见的内核数据结构包括:
- 进程控制块(PCB): 存储进程信息。
- 调度队列: 存储准备运行的进程。
- 页表: 存储虚拟内存到物理内存的映射信息。
- 文件系统管理结构: 管理文件及其元数据。
关系:
内核数据结构是操作系统内部的关键组成部分,支持进程调度、内存管理、设备管理等操作。它们与进程地址空间、物理内存的管理紧密相连,确保操作系统能够有效地管理硬件资源和进程执行。
5. 物理内存(Physical Memory)
物理内存是计算机硬件中用于存储数据的实际内存(如RAM)。它是计算机硬件资源的一部分。
关系:
物理内存是操作系统管理的核心资源之一。操作系统通过虚拟内存管理将虚拟地址空间映射到物理内存。物理内存存储进程的实际数据和代码,在进程执行时提供直接的内存访问支持。
6. 虚拟内存(Virtual Memory)
虚拟内存是操作系统提供的一种抽象机制,允许进程使用比物理内存更多的内存,并且为每个进程提供一个独立的虚拟地址空间。虚拟内存通过分页或分段机制实现虚拟地址与物理地址的映射。
关系:
虚拟内存允许操作系统将进程的虚拟地址空间与物理内存解耦合。通过虚拟内存,进程能够访问一个看似连续且独立的地址空间,而操作系统负责将虚拟地址映射到物理内存或磁盘的交换空间上。
7. 代码和数据(Code and Data)
- 代码(Code): 进程的可执行指令,通常存放在进程的代码段(Text Segment)中。
- 数据(Data): 进程在运行时使用的所有数据,包括全局变量、静态变量、局部变量等,存放在数据段(Data Segment)、BSS段、堆、栈等区域。
关系:
代码和数据是进程在运行时的核心内容。操作系统通过进程地址空间管理它们,并将其加载到物理内存中进行执行。代码存放在内存的代码段中,而数据存放在数据段、堆、栈等区域。操作系统通过虚拟内存管理这些区域,并通过页表映射虚拟地址到物理内存。
整体关系总结
- 进程由操作系统创建并管理,其控制信息存储在PCB中。
- 每个进程有独立的进程地址空间,该地址空间由操作系统管理,通过虚拟内存提供对物理内存的访问。
- 内核数据结构(如PCB、页表、调度队列等)用于支持操作系统对进程、内存和资源的管理。
- 物理内存是计算机硬件提供的实际内存,存储进程的数据和代码,操作系统通过虚拟内存将进程的虚拟地址空间映射到物理内存。
- 代码和数据是进程执行的核心内容,操作系统将它们分配到虚拟地址空间的不同区域,并通过物理内存存储和执行。
通过这些元素的协同工作,操作系统能够高效地管理进程、内存和硬件资源,并确保系统的稳定与安全。
相关文章:
穿越虚拟与现实:解密Linux进程的地址空间
在 Linux 操作系统中,每个进程都有独立的虚拟地址空间。虚拟地址空间是操作系统为每个进程提供的抽象内存模型,它使得每个进程都觉得自己拥有独立的内存,而不需要关心物理内存的具体布局。本文将深入探讨 Linux 进程的虚拟地址空间及其管理机…...
什么是MySql的主从复制(主从同步)?
主页还有其他面试题总结,有需要的可以去看一下,喜欢的就留个三连再走吧~ 1.什么是MySql的主从复制原理? 主从复制的核心就是二进制binlog(DDL(数据定义语言)语句和DML(数据操纵语言)…...
C++面向对象编程技术研究
一、引言 面向对象编程(OOP)是一种程序设计方法,它将现实世界中的实体抽象为“对象”,并通过类和对象来实现程序的设计。OOP的核心思想包括封装、继承和多态,这些特性使得程序更加模块化、易于扩展和维护。C作为一种支…...
MySQL 连表查询:原理、语法与优化
目录 引言 什么是连表查询? 连表查询的类型 1. 内连接(INNER JOIN) 2. 左连接(LEFT JOIN) 3. 右连接(RIGHT JOIN) 4. 全连接(FULL JOIN) 5. 交叉连接(…...
力扣2382. 删除操作后的最大子段和
力扣2382. 删除操作后的最大子段和 题目 题目解析及思路 题目要求找到每次删除一个元素的最大字段和 因为删除不好做,可以转删除为添加,用并查集维护当前子段和 两部分合并(两个并查集),三部分求和(两个并查集和一个元素) 代码 class S…...
PMP--题库--一模--纯问题
文章目录 单选题 (每题1分,共170道题)1、 [单选] 根据项目的特点,项目经理建议选择一种敏捷方法,该方法限制团队成员在任何给定时间执行的任务数。此方法还允许团队提高工作过程中问题和瓶颈的可见性。项目经理建议采用…...
C++核心指导原则: 错误处理
C Core Guidelines 整理目录 哲学部分接口(Interface)部分函数部分类和类层次结构部分枚举部分资源管理部分性能部分错误处理 E: Error handling E.1: Develop an error-handling strategy early in a design 翻译: 在设计早期制定一个错误处理策略。原因: 为确保代码的健壮…...
豆包、扣子等产品如何与CSDN合作?
要实现CSDN开发者社区与豆包、扣子等产品的深度合作,构建创作者Agent生态体系,可通过以下结构化方案实现技术、生态与商业价值的闭环(含具体实施路径与数据指标): 一、战略合作框架搭建 开放平台互通 建立三方API网关&…...
C#开发——ConcurrentDictionary集合
ConcurrentDictionary<TKey, TValue> 是 C# 中一个专为多线程场景设计的线程安全字典集合,位于 System.Collections.Concurrent 命名空间中。它允许多个线程同时对字典进行读写操作,而无需额外的同步措施。 一、集合特征 此集合有如下特征…...
CSS `transform` 属性详解:打造视觉效果与动画的利器
CSS transform 属性详解:打造视觉效果与动画的利器 引言一、transform 属性简介二、平移(Translation)三、旋转(Rotation)四、缩放(Scale)五、倾斜(Skew)六、组合变换&am…...
Python 进阶特性深度解析:从语法糖到内存管理的统一视角
生成式(推导式)的用法与内存效率分析 Python 的推导式不仅仅是语法糖,它们在内存管理和性能方面有着深刻的影响。理解推导式的工作原理,有助于我们写出更高效的代码。 推导式的内存模型分析 列表推导式在 CPython 解释器中的实现实际上比等价的 for 循环更为高效: # 列…...
eclipse配置Spring
1、从eclipse下载Spring工具 进入 help – install new software… ,如下图: 点击 add ,按以下方式输入: Name : Spring Location : http://dist.springsource.com/release/TOOLS/update/e4.10/ 之后点击 add ,等待…...
属性绑定
双大括号不能在html属性中使用,想要响应式地绑定一个属性,应用v-bind指令 <script > export default{data(){return{dynamicId:"appid",dynamicClass:"appclass"}} } </script><template><div v-bind:id"…...
深入讲解微信小程序 <canvas> 标签的 type=“2d“属性
在微信小程序开发中,<canvas> 组件是一个非常强大的工具,允许开发者创建动态图形和动画。然而,正确设置 <canvas> 的 type 属性是确保其正常工作的关键之一。本文将深入探讨 type"2d" 属性的重要性、使用场景及其在实际…...
基于PSO-LSTM长短期记忆神经网络的多分类预测【MATLAB】
一、研究背景与意义 在时间序列分类、信号识别、故障诊断等领域,多分类预测任务对模型的时序特征捕捉能力提出了极高要求。传统LSTM网络虽能有效建模长程依赖关系,但其性能高度依赖超参数的选择,例如隐含层神经元数量、学习率、迭代次数等。…...
Linux----线程
一、基础概念对比 特性进程 (Process)线程 (Thread)资源分配资源分配的基本单位(独立地址空间)共享进程资源调度单位操作系统调度单位CPU调度的最小单位创建开销高(需复制父进程资源)低(共享进程资源)通信…...
自注意力机制和CNN的区别
CNN:一种只能在固定感受野范围内进行关注的自注意力机制。CNN是自注意力的简化版本。自注意力:具有可学习感受野的CNN。自注意力是CNN的复杂形态,是更灵活的CNN,经过某些设计就可以变为CNN。 越灵活、越大的模型,需要…...
【qt链接mysql】
首先根据自己qtcreater 下载mysql安装包 将mysql安装目录下的如下目录中的xxx\MySQL\MySQL Server 5.7\lib\libmysql.dll 拷贝到QT目录C:\Qt\5.7\mingw53_32\bin 下(当前这个也是我电脑上的Qt路径,请找到你Qt对应的bin路径) 直接在文win11上…...
Parameter 与 Param 有什么区别
Parameter 与 Param Parameter 与 Param 意思相同,在大多数情况下可以互换使用,它们在用法和语境有一些细微的区别 1、Parameter Parameter 是一个完整的单词,是正式术语,广泛用于数学、统计学、计算机科学、工程等领域 在数学…...
【前端】【功能函数】treeMapEach,对每个节点进行自定义转换的实用函数
一、功能说明 这是一个递归遍历树形结构数据,并对每个节点进行自定义转换的实用函数。它会对原始树中的每个节点执行 conversion 函数,最终生成一个包含转换后结果的新树结构。 二、核心作用 树形结构遍历:深度优先递归遍历所有子节点数据…...
C#初级教程(5)——解锁 C# 变量的更多奥秘:从基础到进阶的深度指南
一、变量类型转换:隐式与显式的门道 (一)隐式转换:编译器的 “贴心小助手” 隐式转换是编译器自动进行的类型转换,无需开发者手动干预。这种转换通常发生在将取值范围小的数据类型赋值给取值范围大的数据类型时&#…...
初步学习java 动态代理
前言 在学习 动态代理知识之前,可以先了解 反射 反射的复习-CSDN博客 场景 我们知道,一些大明星开演出会,要收门票,准备场景啥的。但很显然 明星,他们主要还是 唱歌,跳舞,和粉丝互动。那么 其…...
QT 基础知识点
1.基础窗口类QMainWindow qDialog Qwidget 随项目一起创建的窗口基类有三个可选QMainWindow qDialog Qwidget 1.1 Qwidget 是所有窗口的基类,只要是他的子类,或子类的子类,都具有他的属性。 右键项目 Add New -> Qt qt设计师界面类&am…...
unity学习53:UI的子容器:面板panel
目录 1 UI的最底层容器:canvas 1.1 UI的最底层容器:canvas 1.2 UI的合理结构 2 UI的子容器:面板panel 2.1 创建panel 2.2 面板的本质: image ,就是一个透明的图片,1个空容器 3 面板的属性 4 面板的…...
Qt如何将数据传入labview,Qt又如何从labview中读取数据?
Qt如何将数据传入labview,Qt又如何从labview中读取数据? Qt如何将数据传入labviewQt如何从labview中读取数据 Qt如何将数据传入labview Qt如何从labview中读取数据...
JWT使用教程
目录 JWT (JSON Web Token)1. JWT简介(1) 什么是JWT(2) JWT有什么用(3) JWT认证方式 2. JWT的组成部分3. 签名的目的4. JWT与Token的区别5 JWT的优势6 JJWT签发与验证token(1) 引入依赖(2) 创建 Token(3) 解析Token(4) 设置过期时间(5) 自定义claims 7. JWT自定义工具类 JWT (J…...
数据结构——静态顺序表,动态顺序表
线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是⼀种在实际中⼴泛使 ⽤的 数据结构,常⻅的线性表:顺序表、链表、栈、队列、字符串... 线性表在逻辑上是线性结构,也就说是连续的⼀条直线。但是在…...
前端Sass面试题及参考答案
目录 什么是 Sass? Sass 和 CSS 的主要区别是什么? Sass 中如何处理列表? Sass 中如何处理映射(map)? Sass 中如何使用函数? Sass 中如何使用内置函数? Sass 中如何设置默认值? Sass 中的 @function 和 @mixin 有什么区别? Sass 中如何实现模块化? Sass 中…...
ubuntu20.04音频aplay调试
1、使用指定声卡,aplay 播放命令 aplay -D plughw:1,0 test2.wav2、 录音 arecord -Dhw:1,0 -d 10 -f cd -r 44100 -c 2 -t wav test.wav3、各个参数含义 -D 指定声卡编号 plughw:0,0 //0,0代表card0,device0,可以通过arecord -l获取 -f 录音格式 S16_LE…...
比特信噪比与信噪比SNR的换算公式
在无线通信系统中,比特信噪比与信噪比(SNR,通常指符号信噪比Es/N0)的换算: 核心公式 E b N 0 SNR R ⋅ log 2 M \boxed{ \frac{E_b}{N_0} \frac{\text{SNR}}{R \cdot \log_2 M} } N0EbR⋅log2MSNR 或…...
RTSP场景下RTP协议详解及音视频打包全流程
RTSP场景下RTP协议详解及音视频打包全流程 一、RTSP与RTP的关系 RTSP:负责媒体会话控制(DESCRIBE、SETUP、PLAY、PAUSE),通过SDP协商传输参数(端口、编码格式、封装模式)。RTP:实际传输音视频数…...
java练习(39)
ps:题目来自力扣 三数之和 给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k ,同时还满足 nums[i] nums[j] nums[k] 0 。请你返回所有和为 0 且不重复的三元组。 注意:答案中不可以…...
2.24DFS和BFS刷题
洛谷P2895:用BFS走出危险区域,危险区域存在时间,我们用ma记录最快变成危险区域的时间, 然后每次枚举时间1然后跟ma数组比较看能不能走,然后时间复杂度为O(305^2)。 #include<iostream> #include<cstring>…...
基于YOLO11深度学习的运动鞋品牌检测与识别系统【python源码+Pyqt5界面+数据集+训练代码】
《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…...
赛前启航 | 三场重磅直播集结,予力微软 AI 开发者挑战赛!
随着微软 AI 开发者挑战赛的火热进行,赛前指导直播已成为众多参赛者获取技术干货、灵感碰撞和实战技巧的绝佳平台。继前两期的精彩呈现,第三、四、五期直播即将接连登场,为开发者们带来更加深入的 AI 技术剖析和项目实战指引。无论你是想进一…...
MySQL数据库连接池泄露导致MySQL Server超时关闭连接
前言 最近做项目,发现老项目出现xxx,这个错误其实很简单,出现在MySQL数据库Server端对长时间没有使用的client连接执行清楚处理,因为是druid数据库,且在github也出现这样的issue:The last packet successf…...
Deepseek和Grok 3对比:写一段冒泡排序
1、这是访问Grok 3得到的结果 2、grok3输出的完整代码: def bubble_sort(arr):n len(arr) # 获取数组长度# 外层循环控制排序轮数for i in range(n):# 内层循环比较相邻元素,j的范围逐渐减少for j in range(0, n - i - 1):# 如果当前元素大于下一个元…...
EX_25/2/22
找到第一天mystring练习,实现以下功能 mystring str "hello" mystring ptr "world" str str ptr; str ptr str[0] H #include <iostream> #include <cstring> #include <cstdlib> #include <unistd.h> #in…...
el-select滚动获取下拉数据;el-select滚动加载
el-select下拉获取数据 1.解决问题2.封装MyScrollSelect组件3.使用MyScrollSelect组件 1.解决问题 场景:下拉数据量过大,后端提供一个分页查询接口;需要每次滚动加载下一页的下拉数据 且单选的状态,需要支持回显,通过n…...
Spring Boot面试题
Spring Boot面试题 基础概念 Q1: Spring Boot的核心特性有哪些? public class SpringBootBasicDemo {// 1. 自动配置SpringBootApplicationpublic class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class…...
STM32-智能小车项目
项目框图 ST-link接线 实物图: 正面: 反面: 相关内容 使用L9110S电机模块 电机驱动模块L9110S详解 | 良许嵌入式 一、让小车动起来 新建文件夹智能小车项目 在里面复制19-串口打印功能 重命名为01-让小车动起来 新建文件夹motor&…...
SAP-ABAP:ABAP第一代增强详解
在SAP ABAP开发中,第一代增强(First-Generation Enhancement) 是早期用于扩展标准程序功能的传统技术,主要通过预定义的增强点(Enhancement Points)实现。以下是详细解析: 一、第一代增强的核心…...
20分钟 Bash 上手指南
文章目录 bash 概念与学习目的第一个 bash 脚本bash 语法变量的使用位置参数管道符号(过滤条件)重定向符号条件测试命令条件语句case 条件分支Arrayfor 循环函数exit 关键字 bash 脚本记录历史命令查询文件分发内容 bash 概念与学习目的 bash࿰…...
地铁站内导航系统:基于蓝牙Beacon与AR技术的动态路径规划技术深度剖析
本文旨在分享一套地铁站内导航系统技术方案,通过蓝牙Beacon技术与AI算法的结合,解决传统导航定位不准确、路径规划不合理等问题,提升乘客出行体验,同时为地铁运营商提供数据支持与增值服务。 如需获取校地铁站内智能导航系统方案文…...
WordPress R+L Carrier Edition sql注入漏洞复现(CVE-2024-13481)(附脚本)
免责申明: 本文所描述的漏洞及其复现步骤仅供网络安全研究与教育目的使用。任何人不得将本文提供的信息用于非法目的或未经授权的系统测试。作者不对任何由于使用本文信息而导致的直接或间接损害承担责任。如涉及侵权,请及时与我们联系,我们将尽快处理并删除相关内容。 0x0…...
滴水逆向_引用_友元函数_运算符重载
作业: 运算符号重载实现。 struct Person { public:int x;int y; public:Person(){this->x 10;this->y 20;}Person(int x, int y){this->x x;this->y y;}//申明友元函数void Printf(const Person& p){printf("%d %d",p.x,p.y);}/…...
git中,如何查看具体单个文件的log
在 Git 中,可以使用多种方式查看单个文件的提交日志(Log),以下详细介绍不同场景下的查看方法: 目录 一、基本命令查看文件的完整提交日志 二、查看文件提交日志并显示差异内容 三、限制显示的提交日志数量 四、按…...
如何生成traceid以及可视化展示
根据你的需求,以下是一些可以生成唯一 traceId 并用于分布式链路追踪的工具和项目,这些项目支持生成唯一的 traceId,并将其用于日志记录和分布式追踪: 1. OpenTelemetry OpenTelemetry 是一个开源的观测框架,支持生成…...
2024 ICPC香港站 L.Flipping Paths的一种解法
太变态了,场上被硬控了两个小时,最后20分钟思路熬出来了但是没写对~,糖完了。怎么说呢,香港站这样的轻量级赛站,这次强队也很少,导致很多题目的难度升级了,这道L题是一道银牌题,不少…...
Uniapp 开发中遇到的坑与注意事项:全面指南
文章目录 1. 引言Uniapp 简介开发中的常见问题本文的目标与结构 2. 环境配置与项目初始化环境配置问题解决方案 项目初始化注意事项解决方案 常见错误与解决方案 3. 页面与组件开发页面生命周期注意事项示例代码 组件通信与复用注意事项示例代码 样式与布局问题注意事项示例代码…...