【Linux】搞懂进程地址空间
创始人
2024-02-07 11:39:05
0

文章目录

    • 1、从程序地址空间开始
      • 1.1 在C/C++中看到的地址实际是?
      • 1.2 感性理解虚拟地址空间
    • 2、进程地址空间
      • 2.1 进程地址空间是怎样被描述的?
      • 2.2 进程地址空间和内存的关系
      • 2.3 为什么需要进程地址空间?

1、从程序地址空间开始

1.1 在C/C++中看到的地址实际是?

在之前,我们学习C/C++的时候看过一个地址空间,它是这样的。
我们带着疑问,这个所谓的内存区域实际是计算机的物理内存吗?
在这里插入图片描述
我们在Linux中,通过一个程序验证一下。
首先fork被调用后创建子进程,操作系统为了管理一个进程,在父进程创建子进程时,必须拷贝父进程的数据结构(子进程按照父进程为模板)。

  1 #include 2 #include 3 4 int g_val = 0;5 6 int main()7 {8     pid_t id = fork();9     if(id < 0)10     {11         perror("fork fail\n");12         return 0;13     }14     else if(id == 0)15     {16         //子进程17         printf("child[%d]: %d : %p\n", getpid(), g_val, &g_val);18     }                                                                                    19     else                                             20     {                                     21         //父进程     22         printf("parent[%d]: %d : %p\n", getpid(), g_val, &g_val);23     }              24     sleep(1);                                                                                                                                       25                                         26     return 0;          27 }

结果显示在同一个地址空间。
在这里插入图片描述
修改一下程序
我们并不能确定父子进程哪个先跑完,所以给父进程代码sleep3秒,让子进程修改g_val后先跑完再执行父进程。

  1 #include 2 #include 3 4 int g_val = 0;5 6 int main()7 {8     pid_t id = fork();9     if(id < 0)10     {11         perror("fork fail\n");12         return 0;13     }14     else if(id == 0)15     {16         //子进程17         g_val = 100;18         printf("child[%d]: %d : %p\n", getpid(), g_val, &g_val);                         19     }                                                20     else                                  21     {              22         //父进程                              23         sleep(3);                                                                                                                                   24         printf("parent[%d]: %d : %p\n", getpid(), g_val, &g_val);25     }                                   26     sleep(1);          27 28     return 0;                                                      29 }

在这里插入图片描述

从结果上看,由于进程之间是独立的,所以在子进程修改g_val后,父进程的值依然不变,这很正常,但是竟然出现了同一个空间出现两个不同的值。

这是我们后续需要解释的一个现象。
不过在此前,我们需要认识到,物理内存是不可能一个地址存两个不同的值的,所以上述的地址空间不是在内存中,其实我们上述所指的地址空间其实是一个虚拟地址空间

1.2 感性理解虚拟地址空间

虚拟地址空间其实就是让程序自己认为独占内存空间。(其实不是)

通过一个故事理解。
操作系统比喻成一个富老爸,这个老爸假设有10亿资产(对应内存空间),而这个富老爸有3个私生子(3个进程),他们彼此并不知道对方的存在。

每个进程以为自己独占空间,其实没有。
富老爸为了让每个私生子做好自己的事,给每个人都偷偷的画了一个饼:“ 只要你努力变得有出息,在我死后我就把我的10亿资产都继承给你 ”(虚拟地址空间)。

进程向内存申请空间,但如果太多会被操作系统拒绝
有个儿子可能在自己努力的道路上遇到点挫折,需要在老爸那里借点钱(进程向内存申请空间),但是这个钱(内存空间)不会很多,如果很多的话,老爸(操作系统)会拒绝的。


虚拟地址空间是由操作系统画的一个饼,那么操作系统是如何画的呢?

公司给员工画饼,员工需要记忆好,不然画饼没有意义。
画饼本质:在你大脑里构建一副蓝图 – 数据结构struct 蓝图

如果公司给400个员工每个画了一个饼,员工需要被管理,每个员工对应的饼也要管理,不然认错了。
如果操作系统给400个进程每个构建了一个虚拟地址空间,进程需要被管理,每个对应的虚拟空间也要被管理。
那么就需要对每个虚拟空间进行描述,创建对应结构体,再利用数据结构组织起来。
地址空间的本质:是内核的一种数据结构!struct mm_struct。

所以我们知道了,在操作系统中,进程地址空间就是一个虚拟的空间,那么我们如何描述它呢?

2、进程地址空间

2.1 进程地址空间是怎样被描述的?

在此之前,我们需要对地址空间有一个基础。
下面对32位进行讨论

  1. 地址空间描述的基本空间大小是字节。
  2. 32位下 -> 2^32个地址(00 00 00 00 -> ff ff ff ff)。
  3. 内存空间2^32个字节 就是 4GB空间。
  4. 每个字节都要有唯一的地址。(地址最大作用就是保证唯一性)

在这里插入图片描述
(1个字节是每个地址对应空间大小,地址4个字节是指自身大小)

  • 描述进程地址空间

操作系统会为每个进程创建一个虚拟的进程地址空间,对应的进程PCB内会有一个指针(struct mm_struct *mm;)指向这个空间,而这个空间的描述在内核代码中就是一个结构体(struct mm_struct { … })。

进程地址空间通过对应的结构体进行描述,再通过相应的数据结构进行管理。
每个进程对应的进程地址空间,不是一开始就给4GB空间的,而是通过数据结构修改结构体变量进行调整空间大小。
在这里插入图片描述

Linux内核部分代码:
对应PCB,在进程各种属性中,有一个mm指针管理着内存信息。
在mm_struct结构体中,有着维护各种区域字段的属性信息。

struct task_struct {...struct mm_struct *mm; //进程内存管理信息...
}struct mm_struct {...unsigned long total_vm, locked_vm, shared_vm, exec_vm;unsigned long stack_vm, reserved_vm, def_flags, nr_ptes;unsigned long start_code, end_code, start_data, end_data;     /*维护代码区和数据区的字段*/unsigned long start_brk, brk, start_stack;       /*维护堆区和栈区的字段*/unsigned long arg_start, arg_end, env_start, env_end;  /*命令行参数的起始地址和尾地址,环境变量的起始地址和尾地址*/...
}

所以我们知道了,所谓进程地址空间,其实就是一个进程PCB属性指向的一个数据结构,通过相应数据结构操作调整这个结构体变量就可以调整对应虚拟空间大小。

但是,程序是要加载到内存的,进程地址空间和内存有什么关系呢?

2.2 进程地址空间和内存的关系

程序加载到内存,操作系统会为每一个程序创建匹配的进程控制块并管理起来,每一个进程控制块指向加载到内存的程序,而在这个指向中,进程地址空间是虚拟地址,虚拟地址是如何与内存的物理地址打交道的呢?

  • 页表的使用

当一个程序将代码和数据加载到内存,操作系统创建对应的PCB同时为进程创建进程地址空间。

当有一个int a = 10;加载到内存中,对应进程地址空间就有一个虚拟地址,内存中也有一个物理地址。

操作系统中进程自己的页表,将对应的虚拟地址和物理地址保存并匹配起来,这样就能使得虚拟地址通过映射访问到物理空间。
当我们需要修改一个数据(比如将a = 10 改为 a = 100时),我们看到的&a是虚拟地址,就能直接通过页表访问物理空间将a修改为100。
在这里插入图片描述
这里粗略的了解一下页表的功能,以上所有工作都是由操作系统做的

必须认识到,进程地址空间只是一个“饼”,实际上根本没有4GB,操作系统按需求分配给进程空间,其实也不会分配很多。
拓展知识:

  1. 内存被使用时基本单位是4KB。
  2. 一个4KB空间称为页。
  3. 进程地址空间由于地址都是连续的,所以也被称作线性地址。
  4. 虚拟地址空间包括进程地址空间和页表

2.3 为什么需要进程地址空间?

  • 为了数据安全
    如果让进程之间访问物理内存,要是出现越界访问呢?

    越界访问可能使得一些重要数据被篡改,非常不安全,但这只能证明直接访问物理内存不行。

    所有进程的虚拟地址空间中的页表不是只做映射,页表会根据请求的合理进行判断,不合理的请求会拒绝。

  • 保证进程独立性
    在之前,我们看到同一个虚拟空间存储着两个不同的值这个现象,接下来我们来探讨这个现象。
    在这里插入图片描述

fork调用之后,父子进程共享后续代码,当子进程对共享空间修改时,操作系统先会对原空间进行拷贝,再修改子进程对应的页表映射,最后再让子进程修改数据。

操作系统为了保证进程的独立性,做了很多工作。通过进程地址空间,通过页表,让不同进程映射到不同物理内存。

这里是引用
进程 = 内核数据结构(PCB) + 加载到内存的代码和数据。
进程地址空间和页表体现了内核数据结构的独立性,写时拷贝也体现了数据的独立性,所以进程具有独立性。

  • 方便直接使用编译器的编码地址(了解)

这里是引用

拓展知识:
逻辑地址有两种构建方式:
1、用32位线性编址方式。
2、从0开始,通过区域起始地址+偏移量方式编址,加载到物理内存后将物理空间起始地址+偏移量方式编址。

本章完~

相关内容

热门资讯

第一学期中班幼儿评语 第一学期中班幼儿评语(精选15篇)  在平平淡淡的日常中,大家都写过评语吧,评语的内容包括被考评者的...
王小波的经典语录100句   王小波的小说既继承了年代对爱情与革命权力关系的思考,具有强烈启蒙意味,也顺应了年代世俗化潮流。接...
经典祝愿高考成功寄语 经典祝愿高考成功寄语(通用90句)  六月参加高考,准备还得趁早,心态一定摆正,付出必有回报,毕竟熬...
电影的观后感 电影的观后感  在观看完一部作品以后,能够给我们不少启示,这时候最关键的观后感不能忘了。但是观后感有...
利益关系经典语录 利益关系经典语录  在日常的学习、工作、生活中,大家都知道一些经典的语录吧,语录是指一个人的说话记录...
哆啦a梦语录 哆啦a梦语录  01、骗人有风险,说谎要谨慎。  02、日子就像偷跑的小孩,无声地溜走。  03、知...
感人的情书经典语录   在很多超感人的情书中,是有一些情书经典语录起到关键作用。小编今天收集了超感人情书经典语录,希望得...
高中生毕业寄语 高中生毕业寄语4篇  在日常的学习、工作、生活中,大家总免不了要接触或使用寄语吧,寄语是所传的、寄托...
优秀班干部获奖感言 优秀班干部获奖感言优秀班干部获奖感言尊敬的老师,亲爱的同学: 大家晚上好!我是S,今天很高兴作为获奖...
最新感人经典语录 最新感人经典语录  1其实,我不是一定要等你,只是等上了,就等不了别人了。《朝露若颜》  2如果世界...
小说我的美女大小姐经典语录   揭穿谎言背后的谎言多累啊!还不如站的离你远点儿,看着你怎么在谎言中尽情的表演  ——李兴禹《我的...
个性早安寄语 常用个性早安寄语汇总75句  我只是想写一封信给你,寄信人在河这头,收信人在河那头。隔开我们的这条河...
假期家长评语怎么写 假期家长评语怎么写  假期我们家长任务是比较大的,许多家长都不知道怎么去写这个假期表现评语,假期家长...
一年级开学典礼校长致辞 一年级开学典礼校长致辞(精选5篇)  在平平淡淡的学习、工作、生活中,大家都对致辞很是熟悉吧,致辞是...
初中学生综合素质评语 初中学生综合素质评语大全  在生活、工作和学习中,大家总少不了要接触或使用评语吧,评语可有效引导被评...
毕业班主任寄语 毕业班主任寄语通用15篇  在平日的学习、工作和生活里,大家总少不了要接触或使用寄语吧,寄语的种类很...
谈“死亡”话题 谈“死亡”话题  死亡指丧失生命,生命终止,停止生存,是生存的反面。哲学上说,死亡是生命(或者事物件...
情人节温馨寄语 情人节温馨寄语集合15篇  在学习、工作、生活中,说到寄语,大家肯定都不陌生吧,寄语是所传的话语,有...
初中毕业寄语 初中毕业寄语(合集15篇)  在学习、工作或生活中,大家都尝试过写寄语吧,寄语是人们所传的话语,有时...
生日的寄语 生日的寄语(精选15篇)  在我们平凡的日常里,要用到寄语的情况还是蛮多的,借助寄语人们可以表达心中...