文章目录
一、虚拟地址
什么是虚拟地址 ? 什么是物理地址 ?
// 有这样一个代码
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
//全局变量 , 父和子都可用
int global = 100;
int main()
{
printf("我是父进程 , 我的 pid = %d , 我的父进程 pid = %d , global = %d , &global = %p\n", getpid(),getppid(),global,&global);
printf("-----------------------------------------------------------------------\n");
//创建子进程
pid_t id = fork();
if(id < 0)
{
printf("fork err !\n");
return 1;
}
else if(id == 0)
{
//child
while(1)
{
printf("我是子进程 , 我的 pid = %d , 我的父进程 pid = %d , global = %d , &global = %p\n",getpid() , getppid(),global++,&global);
sleep(1);
//子进程修改全局 global
}
}
else
{
//father
while(1)
{
printf("我是父进程 , 我的 pid = %d , 我的父进程 pid = %d , global = %d , &global = %p\n",getpid() , getppid(),global,&global);
sleep(1);
}
}
return 0;
}
二、什么是进程虚拟地址空间 ?
地址空间的分布图
以上的图只是形象的划分 , 那么在 Linux 操作系统中是怎样做到这样的划分的呢 ?
1. 怎么划分各个区域 ?
进程虚拟地址空间分为很多区域 , 有 : 代码区 , 数据区 , 栈区 , 堆区 , 共享区 !
那这些区域在系统中怎么被划分呢 ?
2 . 进程虚拟地址空间是什么 ?
答 : 是一个数据结构 ! mm_struct
3 . 本小节要知道的内容
三、深入剖析进程虚拟地址空间
1 . 为什么进程虚拟地址空间要被管理呢 ?
这里讲一个例子 :
2 . 虚拟地址空间与内存
2.1 . 虚拟地址空间怎么骗程序 ?
2.2 . 虚拟地址空间怎么与内存交互呢 ? (页表初识)
答 : 通过页表 !
● 页表初识
● 页表映射
● 为什么父或子进程中变量地址一样 , 值不一样呢 ? (虚拟地址空间底层) (回答 一 中的问题 !)
这里举的例子是 : 一 中的代码所面临的问题 .
为什么 ???
1 . 回答问题1 , 地址为什么一样 ?
2 . 回答问题2 , 为什么一方改变 , 一方值不变 ?
本节重点
3 . 进程虚拟地址空间在 Linux 中的存在形式
前面也提到了 , 一个进程有自己的 mm_struct , 这个 mm_struct 里面又是起始地址和结束地址 .
那进程也会有很多呀 , 那 mm_struct 要不要被管理起来呢 ? 答 : 要 !
linux内核使用 vm_area_struct
结构来表示一个独立的虚拟内存区域(VMA) .
即 : 进程虚拟地址空间中的每一个区域都用 vm_area_struct 这个数据结构管理起来 !
4 . 为什么要有进程虚拟地址空间呢 ?
有的人可能会想 , 进程虚拟地址空间最终访问数据不是还有映射物理内存吗 ?? 那就意味着最终还是要用物理内存吗 ?? 为什么不直接去访问呢 ??
1 . 让地址从 “无序” 变 “有序”
这里的有序 , 不是绝对有序 !
看一个代码 :
int main()
{
// 堆上申请空间
char *heap_mem = (char*)malloc(10);
char *heap_mem1 = (char*)malloc(10);
char *heap_mem2 = (char*)malloc(10);
char *heap_mem3 = (char*)malloc(10);
printf("heap addr: %p\n", heap_mem); //heap_mem(0), &heap_mem(1)
printf("heap addr: %p\n", heap_mem1); //heap_mem(0), &heap_mem(1)
printf("heap addr: %p\n", heap_mem2); //heap_mem(0), &heap_mem(1)
printf("heap addr: %p\n", heap_mem3); //heap_mem(0), &heap_mem(1)
return 0;
}
2 . 虚拟内存可以保护物理内存
将从以下两方面回答 !