【Linux】--程序地址空间

一、程序地址空间

下面我们先看一段代码的运行情况:

代码如下:

运行结果如下:

我们上面的代码是先创建一个全局变量,然后创建一个子进程,然后在子进程中对这个全局变量进行修改,然后我们的父进程的话就不会对其进行修改,然后我们将父子进程对于这个变量进行取地址,我们很惊奇的发现,其两个的地址是一样的。

那么我们就有疑问了,我们一个地址,怎么会有两幅面孔呢?

所以我们可以肯定的是,其访问的地址,肯定不是我们的真实的物理地址。

那么我们在这里就引入我们的一个新的概念,虚拟地址。

首先我们再复习一下:

进程=PCB数据结构对象+数据和代码

我们的操作系统创建一个进程的时候,会由进程中的task_struct结构体中的PCB指向这个虚拟地址,虚拟地址和物理内存地址之间,使用了一个页表进行映射,所以其虚拟地址和物理地址之间是可以互相映射的。

那么这么做的作用是啥呢?

就好比如我们去银行取钱,那么我们中间需要通过取款机,或者柜台人员一样,我们用户是无法直接去金库拿钱的吧,这是操作系统为了保护我们的物理内存的一种方式。

我们的内存中,是有很多的进程的,那么为了防止进程之间影响,所以这样操作。

那么这么做的好处就是我们的用户可以关心内存的实际布局,这个交给操作系统进行管理,我们只需要关心虚拟内存即可。

下面是我们的虚拟内存空间和物理内存之间通过页表进行联系的示意图:

页表的左边是虚拟地址的编码,右边的是物理内存对应的编码。

前面我们知道,创建一个进程,我们是先创建其内核数据结构,然后再加载数据和代码的,那么我们操作系统对于一些不着急运行的进程,那么会先不加载其数据和代码,等到要运行这个进程的时候才会将其数据和代码加载,这种就叫做懒加载。

我们创建一个子进程,子进程会和父进程共享数据和代码,在对于数据修改前,我们的页表中,对于虚拟地址和物理内存地址的映射中,其实还有一个内容,就是权限,其一开始,只能是只读的状态,然后当我们的子进程发生了数据的修改,那么物理内存就会进程报错反馈,那么操作系统此时就会立马进行反馈,然后就会在物理内存中申请一块空间,给子进程,这种叫做写时拷贝。

所以说,子进程和父进程的虚拟地址虽然一样,但是其真实的物理地址是不一样的。

相关推荐
wj3055853787 小时前
课程 9:模型测试记录与 Prompt 策略
linux·人工智能·python·comfyui
abigriver7 小时前
打造 Linux 离线大模型级语音输入法:Whisper.cpp + 3090 显卡加速与 Rime 中英混输终极调优指南
linux·运维·whisper
wangqiaowq7 小时前
windows下nginx的安装
linux·服务器·前端
YYRAN_ZZU8 小时前
Petalinux新建自动脚本启动
linux
charlie1145141918 小时前
嵌入式Linux驱动开发pinctrl篇(1)——从寄存器到子系统:驱动演进之路
linux·运维·驱动开发
Agent手记8 小时前
异常考勤智能预警与处理与流程优化方案 | 基于企业级Agent的超自动化实战教程
运维·人工智能·ai·自动化
于小猿Sup9 小时前
VMware在Ubuntu22.04驱动Livox Mid360s
linux·c++·嵌入式硬件·自动驾驶
cen__y9 小时前
Linux12(Git01)
linux·运维·服务器·c语言·开发语言·git
不仙52010 小时前
VMware Workstation 26.0.0 在 Ubuntu 24.04 (内核 6.17.0) 上的安装与内核模块编译问题
linux·ubuntu·elasticsearch
1892280486111 小时前
NY352固态MT29F32T08GWLBHD6-24QJ:B
大数据·服务器·人工智能·科技·缓存