【Linux】--程序地址空间

一、程序地址空间

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

代码如下:

运行结果如下:

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

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

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

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

首先我们再复习一下:

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

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

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

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

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

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

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

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

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

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

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

相关推荐
益达丫30 分钟前
Socket编程揭秘:端口、IP与进程通信的底层逻辑
linux·笔记
比兔代理40 分钟前
正向代理与反向代理技术辨析,为什么代理 IP 属于正向代理
服务器·网络·http·ip
Wang's Blog2 小时前
Java 接入Redis: 通用命令与键管理
java·服务器·redis
Wang's Blog2 小时前
Java 接入Redis: 列表集合与有序集合操作命令
java·服务器·redis
蓝速科技2 小时前
会议室门牌公告通知发布选型与落地指南丨蓝速科技
大数据·运维·数据库·人工智能·科技
Ivanqhz3 小时前
SVD++算法
java·服务器·网络·深度学习·神经网络
chicheese3 小时前
Linux 面试速查表:从初级到高级,附高频场景答题模板
linux·运维
Linux-lucky3 小时前
32-38-Linux学习之旅之MySQL综合
linux·运维·学习·mysql·ubuntu
智能运维指南4 小时前
2026年ITSM系统怎么选?四款主流方案与五维评估模型
运维·itsm·嘉为蓝鲸
vortex54 小时前
常用终端模拟器全面对比:Kitty、WezTerm、Ghostty 与 Konsole
linux