医药网站开发,wordpress境外支付,济南网站维护公司,搭建网页平台目录
引入问题
测试代码
引入地址空间
故事1#xff1a; 故事二#xff1a;
解决问题
为什么有虚拟地址空间
扩展
扩展1#xff08;没有地址空间#xff0c;OS如何工作#xff09; 扩展2 #xff08;代码只读深入了解#xff09; 扩展3#xff08;malloc本质…目录
引入问题
测试代码
引入地址空间
故事1 故事二
解决问题
为什么有虚拟地址空间
扩展
扩展1没有地址空间OS如何工作 扩展2 代码只读深入了解 扩展3malloc本质 扩展4 重新理解地址空间 引入问题 我们引入一个问题这种模型如果不是内存那应该是什么 测试代码 #include stdio.h
#include assert.h
#include unistd.hint g_value 100;//全局变量int main()
{pid_t id fork(); assert(id0);if(id0){//childwhile(1){printf(我是子进程我的id是%d,我的父进程是%d,g_value:%d, g_value: %p\n,\getpid(),getppid(),g_value,g_value);sleep(1);g_value;//只有子进程会进行修改}}else {//fatherwhile(1){printf(我是父进程我的id是%d,我的父进程是%d,g_value:%d, g_value: %p\n,\getpid(),getppid(),g_value,g_value);sleep(2);}return 0;}
}引入地址空间 故事1 假设有一个有10亿美金的大富翁其有四个私生子且彼此不知道彼此不存在人四个都以为自己是唯一继承人富翁跟A说“好好努力做生意以后我的家产都是你的”;富翁跟B说“好好努力以后我的家产都是你的”;富翁跟C说“好好努力以后我的家产都是你的”富翁跟D说“好好努力以后我的家产都是你的”,跟ABCD画大饼画的饼也要管理起来先描述再组织饼-进程地址空间本质就是一个内核数据结构struct mm_struct{} 故事二 小花VS小胖两个小学生闹了矛盾最后在桌子上化了个线画线的本质区域划分 区域划分对线性区域进行1指定的start和end即可完成区域划分 两人相安无事了一阵子过了一段时间双方中的一方通过暴力扩张已经占有整个桌面的70%甚至80%该种行为我们称为扩大区域 修改start\end值即可。 解决问题 我们知道数据和代码真正只能在内存中 fork在返回的时候父子都有了return两次id是不是pid_t类型定义的变量呢返回的本质就是写入、谁先返回谁就让OS发生写实拷贝 同一个变量地址相同其实是虚拟地址相同内容不同其实是被映射到了不同的物理地址 为什么有虚拟地址空间 1 防止地址随意访问保护物理内存与其他进程 2 将进程管理和内存管理进行解耦合 3 可以让进程以统一的视角看待自己的代码和数据 扩展 扩展1没有地址空间OS如何工作 如果没有虚拟地址空间OS如何工作 这种没有虚拟地址空间的会依靠代码存储在物理空间的具体位置来进行工作。 进程管理与内存管理耦合 如果有虚拟地址空间进程工作并不关心其存储在物理内存中的具体位置解耦合 扩展2 代码只读深入了解 代码是只读的深入了解——代码所限定的区域是正文代码虚拟地址空间经过页表映射其权限位写的都是r,对应的只能读取 扩展3malloc本质 申请空间成功但是暂时不用闲置状态也会造成浪费 malloc先申请一个空间假设我们在堆区上申请一个空间即将堆区扩大往上申请然后将虚拟地址填入页表但是物理地址暂时不填同时也不在物理地址中申请空间调用malloc就直接返回。采用缺页中断的方式。 扩展4 重新理解地址空间 我们的程序在被编译的时候没有被加载到内存但是我们的程序内部也有地址 虚拟地址这样的策略不止会影响OS我们的编译器也遵守这样的规则 在Linux中可编译程序ELF格式源代码被编译的时候就是按照虚拟地址空间的方式对代码和数据早早地编好了对应的编制 操作系统在执行main函数之前还有一定的函数例如startup函数所以起点在用户角度看来像是main函数但是实际不是 进程的代码和数据必须一直在内存中吗X