引例
#include <stdio.h>
#include <unistd.h>
int main()
{
int test_num = 0;
pid_t pid = fork();
if(pid == 0)
{
test_num =100;
printf("子进程test_num的值%d,test_num的地址%p\n",test_num,&test_num);
}
else if(pid > 0)
{
printf("父进程test_num的值%d,test_num的地址%p\n",test_num,&test_num);
sleep(1);
}
return 0;
}
观看这个代码,父子进程中的相同变量可以存储两个不同的值?带着这个问题往下看
首先我们先回顾一下那个在C语言和C++学习中的“内存空间分布图”
根据计算机组成原理的知识,在同一个存储单元是不可能存储两个值的,所以我大胆推出,我之前C/C++学的指针地址和%p打印出来的地址都不会物理地址,而是虚拟地址/线性地址。
static关键字对变量的影响
从这个代码可以得出,被static修饰之后的变量c,生命周期从栈区变到了全局数据区。注意:static的修饰只改变了生命周期没有改变作用域,就是变量a虽然放在了全局数据区,但是只能在main函数使用(作用域)
什么是地址空间?
物理地址
在计算机硬件存储中,如图:数据的存储空间由这样的一个金字塔形成越上面的存取速度越快,越下面的存取数据越慢,为什么这样设计呢?1.节省成本,如果这个电脑存储都用cache,价格昂贵,无法让计算机平民化,如果只用存取速度慢的,就会大大的影响CPU的速度。就好像你在微信发文件给a同学,你的网络速度快,而他的网络速度慢,进而导致文件传输慢一个道理。
这里讲得地址空间是指内存,而在电路中,以高低电平作为数据表示,一组二进制排列组合则表示一个存储单元,你的地址总线返回一般为[0,2^32),结论1:物理地址指的是你的二进制排列组合数。
如何理解地址划分
问:对于上面内存空间分布图中,不同空间的分布用什么作用?本质上就是作用域和生命周期的区别。而在操作系统中,我们一直都是秉持的先描述后组织的理念,那本质上就是对内存建立一个结构体,在里面记录每一个区域的空间开始和空间结束。
结论2:用先描述后组织的理念,地址划分其实就是结构体
根据这个两个点的得出总结:进程地址空间是一个结构体,是一个操作物理地址结构体
到这里我们不禁引出一个新的问题:如何操作?
页表
对于这个点,我不过多于深究计算机组成原理的概念知识。我们暂时的认为,这个就是一个表,上面有四列,每一个列的标题为,虚拟地址,物理地址,权限(是否有读取权限),状态(是否载入完毕)
比如,现在我用C语言写了一句char* str = “hello”
,然后就在页表的虚拟地址位置写入字符常量区的地址,而linux的内存管理看到这是字符串常量区的地址值,也会相应的写入对应的物理位置,并在权限那一栏中记录这个变量是只读的,并在状态中记录写入完毕。
回答引例问题
现在我们在回过头来看引例的问题
我们声明了两个相同虚拟地址的变量,对于这种现象页表会去检查,如果有相同的他就会把另一个的物理地址指向不同的地方,分开存储,这样就解释了引例中,为什么父子进程变量名一样,地址一样,而存取的值却不一样的现象。
再谈独立性
在以往文章中,我们说进程由pcb+代码数据组成的,在这里应该再去扩展,进程是由PCB、进程地址空间、页表+代码和数据。而独立性则代表每一个进程都会有他自己独立的进程地址空间、pcb、页表。
为什么会有地址空间
1.让进程以统一的视角看待内存。
2.增加进程虚拟地址空间可以让我们访问内存的时候,增加一个转换的过程,在这个转化的过程中,可以对我们的寻址请求进行审查,所以一旦异常访问,直接拦截,该请求不会到达物理内存,保护物理内存
3.因为有地址空间和页表的存在,将进程管理模块,和内存管理模块进行解耦合
操作系统如何将大文件从硬盘移动到内存中
共识:现代操作系统,几乎不做任何浪费空间和浪费时间的事情,所以操作系统对大文件可以实现分批加载,计算机会使用惰性加载的方式,就是你要用多少内存,我就给你多少内存,不会给多也不会给少。
这种时候会先给你填写虚拟地址,物理地址先不填,在状态那一栏标志还没有加载完。等待加载完毕,再把物理地址那一栏填上。如果显示没有加载完,他会给你缺页中断,等到内存足够,或者cpu时间片轮到你这个进程时候,进入你的缺页中断,接着完成你还没有完成的事。
这样我们就可以实现边使用边加载。
当我们创建进程的时候,实现创建内核数据结构再去加载对应的可执行程序。
总结
在C语言中学习地址空间分布,不是内存,而是进程地址空间本质上是一个结构体用于记录变量的虚拟地址,操作系统通过虚拟地址和页表的映射去物理内存中寻找对应的数据,每一个进程都会有他对应的pcb结构体、进程地址空间、页表,保证每个进程的独立性
标签:物理地址,test,空间,地址,num,内存,进程 From: https://blog.csdn.net/qq_45262721/article/details/142135369