什么是进程地址空间
一、 什么是进程地址空间
💦 观察父子进程在5秒后,全局变量g_val的值和地址
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
int g_val = 0;
int main()
{
printf("begin......%d\n", g_val);
pid_t id = fork();
if(id == 0)
{
int count = 0;
while(1)
{
printf("child pid: %d, ppid: %d, [g_val: %d][&g_val: %p]\n", getpid(), getppid(), g_val, &g_val);
sleep(1);
count++;
if(count == 5)
{
g_val = 100;
}
}
}
else if(id > 0)
{
while(1)
{
printf("father pid: %d, ppid: %d, [g_val: %d][&g_val: %p]\n", getpid(), getppid(), g_val, &g_val);
sleep(1);
}
}
else
{
//TODO
}
return 0;
}
💨结果:
根据我们现有的知识,无可厚非的是前 5 次父子进程的 g_val 的值是一样的,且地址也一样,因为我们没有修改 g_val, 5 次后,子进程把 g_val 的值改了之后,父进程依旧是旧值,这个我们一点都不意外,因为父子共享代码
,数据各自私有
;但匪夷所思的是 5 次后,父子进程的 g_val 的地址竟然也是一样的。
推导和猜测 ???
从上图我们可以知道&g_val
一定不是物理地址(真正在内存中的地址),因为同一个物理地址处怎么可能读取到的是不同的值。所以我们断言曾经所看到的任何地址都不是物理地址,而这种地址本质是虚拟地址
,它是由操作系统提供的,那么操作系统一定要有一种方式帮我们把虚拟地址
转换为物理地址
,因为数据和代码一定在物理内存上存储,这是由冯 • 诺依曼体系结构
规定的。
💦 理解进程地址空间
地址空间在 Linux 内核中是一个mm_struct
结构体,这个结构体没有告诉我们空间大小,但是它告诉我们空间排布情况,比如[code_start(0x1000), code_end(0x2000)]
,其中就会有若干虚拟地址,这是因为操作系统为了把物理内存包裹起来,给每个进程画的一把尺子,这把尺子我们叫进程地址空间。进程地址空间是在进程和物理内存之间的一个软件层,它通过mm_struct
这样的结构体来模拟,让操作系统给进程画大饼
,每一个进程可以根据地址空间来划分自己的代码。
所以我们再回顾:进程地址空间当然不是物理内存,它只是操作系统让进程看待物理内存的方式。
进程地址空间本质是进程看待物理内存的方式,它是抽象出来的概念,其中 Linux 内核中是用mm_struct
数据结构来表示的。这样的话每个进程都认为自己独占系统内存资源(好比每个老婆都认为自己独占10亿);区域划分的本质是将线性地址空间划分成为一个一个的区域[start, end]
;而所谓的虚拟地址本质是在[start, end]
之间的各个地址。
- 点赞
- 收藏
- 关注作者
评论(0)