Linux---进程地址空间

文章介绍了进程地址空间的概念,澄清了C语言中关于内存的误区,指出进程间的地址并不直接对应物理内存,而是通过虚拟地址和页表映射。在Linux中,进程地址空间用于保护数据和内存,实现进程管理与内存管理的解耦,并确保代码执行的统一视角。通过写时拷贝机制,保证了父进程修改不会影响子进程的值。
摘要由CSDN通过智能技术生成

一、打破误区

在C语言学习中,我们接触的物理内存这样的:
在这里插入图片描述
假定这就是物理内存, 那么下面的现象怎么解释。一个变量在父子进程中打印出来的地址是相同的,且修改val的值,子进程的val值没有改变,改变是父进程的。
在这里插入图片描述

在这里插入图片描述
因此证明这并不是物理内存,如果是物理内存,相同地址,一个进程修改,一个进程中的值还是原来的值。
C语言一直以来讲的内存布局有一个自己的名字—进程地址空间。
这里留一个问题:为什么解释一个进程修改,一个进程中的值还是原来的值,是什么原理?可以思考一下🤓🤓


二、Linux中的进程地址空间

2.1 进程地址空间是一段虚拟地址的范围,例如32位系统,从0x00000000到0xffffffff, 进行区域划分,从而分出栈、堆、代码段、共享区等等。由于这样是一种线性结构,因此也叫线性空间。在Linux中,是用mm_struct来表示进程地址空间。

页表
是一种key-value类型的表,进程地址空间和物理内存与页表建立映射,实现虚拟地址转换成物理地址。它的功能不仅如此,能够设定权限(读、写、执行),从而保护物理内存数据。

解答一下上面遗留的问题
是发生了写时拷贝,创建子进程,子进程会继承父进程大部分pcb以及代码段和数据段,还有页表的映射关系。指向的同一块物理内存,当发生数据修改的时候,OS会将修改一方的进程的数据在其他地方开辟空间,并拷贝下来并修改,然后改变页表的映射关系(并未改变虚拟地址)。从而达到父进程修改val的值,子进程的val值不变。
请添加图片描述


三、为什么存在地址空间

3.1 保护数据和物理内存
从反面来看,没有进程地址空间的话,访问物理内存采用的是物理寻址方法,进程是一个接一个加载到内存中,一个程序出现了越界这类的问题,很大概率会修改另一个进程的数据,这样无法保护进程的独立性。
3.2 进程管理与内存管理解耦合
有了进程地址空间,我不需要关注程序是加载到内存的什么位置,我只需要在进程空间所划分的区域内进行操作,这样分成进程管理与内存管理两部分。
3.3 统一视角看待代码
遵守虚拟地址的不仅仅是OS,编译器也需要。源码在编译过程中, 函数地址按照虚拟地址的方式进行编址。运行程序时,CPU从入口函数开始读取,不断运行,当需要call地址时,地址都是虚拟地址,从而虚拟地址空间与页表建立映射,再通过虚拟地址找到内存相应函数的位置,被CPU运行,不断重复这样的步骤,可以做到边加载边运行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值