[Linux]——程序地址空间

程序地址空间

在讲什么是程序地址空间之前我们先看这样一幅图,大家在学习c语言的时候老师一定都给大家看过:
ps:阅读文章前最好知道什么是进程和进程的pcb结构体,前置技能:https://blog.csdn.net/lucky52529/article/details/89261630
在这里插入图片描述
我们今天不研究图中哪个部分放了什么,今天研究的问题是,这幅图指定是内存么?实际上,这幅图指的并不是内存,为什么?让我们一起通过一段代码来研究:

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<unistd.h>
  4 int g_val = 100;
  5 int main()
  6 {        
  7     pid_t id = fork();
  8     if(id == 0)
  9     {    
 10         sleep(1);
 11         printf("Child:%d,%p\n",g_val,&g_val);
 12     }    
 13     else 
 14     {    
 15         sleep(2);
 16         printf("Child:%d,%p\n",g_val,&g_val);                                      
 17     }    
 18     return 0;
 19 }        

打印结果:结果的值和地址与值完全相同,所以我们尝试修改代码
在这里插入图片描述
我们现在将代码修改如下:

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<unistd.h>
  4 int g_val = 100;
  5 int main()
  6 {    
  7     pid_t id = fork();
  8     if(id == 0)
  9     {
 10         g_val = 200;//在此处修改g_val的值
 11         sleep(1);
 12         printf("Child:%d,%p\n",g_val,&g_val);
 13     }
 14     else
 15     {
 16         sleep(2);
 17         printf("Child:%d,%p\n",g_val,&g_val);
 18     }
 19     return 0;                                                                      
 20 }    

但是现在打印的结果让人大吃一惊:地址相同的俩个变量值确实不同的
在这里插入图片描述
所以我们现在推断变量的内容不一样,这里输出的变量肯定不是同一个变量,地址虽然相同,但是这里的地址肯定不是物理地址,而是一个虚拟地址。那么怎么样才能解释清楚这个现象呢,我们先来讲一个小故事。

小故事

  • 从前有一个富商,这个富商拥有10亿的财产并且这个富商还拥有五个私生子,这个五个私生子并不知道互相的存在,但是他们都以为自己可以继承富商10亿的财产。所以,大儿子某天和富商要100w买车,富商给了他100w后他依旧认为自己以后拥有10亿财产,二儿子某天和富商要1000w买房,富商给了他1000w后二儿子也依旧认为自己以后拥有10亿财产。。。。。。

讲了上面的小故事后你现在应该明白了,其实我们上面代码中打印的值相同是因为这里打印的值是俩个不同的值(富商不同的一部分财产),但是之所以地址相同是因为进程现在以为自己可以独占这4G的内存,但是事实上这里打印了虚拟地址(都认为拥有富商的所有财产)

mm_struct

什么是mm_struct?实际上mm_struct就是我们上面说的那张图,叫做进程地址空间也叫虚拟地址空间,他是一个结构体,结构体中存放了描叙各段(代码段,数据段。。。)的范围start和end
在这里插入图片描述
实际上,所有的代码通过虚拟地址映射到物理内存上才能进行一些列的操作,那么他又是怎么映射到物理内存上的呢?
这里又要提一个叫页表的东西

页表是一种特殊的数据结构,放在系统空间的页表区,存放逻辑页与物理页帧的对应关系。 每一个进程都拥有一个自己的页表,PCB表中有指针指向页表。(摘自百度搜索)

页表存放了虚拟地址到物理的关系,那么这种关系的映射又要提到一个MMU的硬件

MMU是Memory Management Unit的缩写,中文名是内存管理单元,它是中央处理器(CPU)中用来管理虚拟存储器、物理存储器的控制线路,同时也负责虚拟地址映射为物理地址,以及提供硬件机制的内存访问授权,多用户多进程操作系统

所以现在用图来描述我们之前代码的现象也就不难理解了:
在这里插入图片描述
他们的变量实际存储在了不同的物理空间,但是虚拟空间的地址刚好的是相同的。这也可以说明进程之间是具有独立性的。

为什么需要进程虚拟地址空间

  • 为了保护内存,因为拥有虚拟地址空间的结构体就可以计算数据有没有按照区域划分存放在自己应该处在的范围中
  • 采用虚拟地址,所有的进程都认为自己独占资源,所以所有的进程都可以以相同的方式来看待每个数据分段,遵循独立性

总结

经过上面的讲解,我们不仅理解了什么是程序的虚拟地址空间,也进一步对进程的创建有了理解,创建一个进程需要创建他的pcb结构体,mm_struct以及页表,并且还要建立与物理内存的映射关系,所以说,创建进程并不是一个容易的事啊。

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值