进程的物理地址空间

一般在Linux下将内存主要划分为已下主要部分,如下图所示,我们知道一个进程的物理空间因该指的是一个进程的活动范围,通过一下代码我i们来观察一下进程中的地址变化。
在这里插入图片描述

#include<stdio.h>
  2 #include<unistd.h>
  3 
  4 int gar_val=100;
  5 
  6 
  7 int main()
  8 {
  9 
 10   pid_t pi=fork();
 11 
 12   if(pi==0)
 13   {
 14   // gar_val=1000;// 这行子进程先不修改变量数据
 15     while(1)
 16     {
 17 
 18       sleep(1);
 19       printf("Child: gar_val:  %d P: %p\n",gar_val,&gar_val); 
 20     }
 21   }
 22   else if(pi>0)
 23     {
 24       sleep(1);                                                                                                                                                                                              
 25       while(1)
 26       {
 27         sleep(2);
 28        printf("Parent: gar_val: %d P :%p\n", gar_val,&gar_val);
 29        }
 30 
 31     }
 32 
 33   return 0;
 34 
 35 }

程序运行结果:
在这里插入图片描述
从程序中我们可以看到系统调用fork函数创建子进程后,父进程和子进程同时访问变量gar_val,并且父子进程访问变量gar_val的值以及地址变量都相同,是因为子进程是父进程的一份拷贝。但是当我们删除注释的哪一行代码,在子进程中修改gar_var的值程序运行的结果如下
在这里插入图片描述
而这时我们在子进程中修改变量数据后,变量gar_var的值变为1000了,而在父进程变量gar_val的值还是100并且父子进程的变量地址也没有变,这是什么原因造成了同一块地址空间的内容所存储的数据不一样的,这样我们将根据可以看出,变量内容不一样,所以父子进程输出的变量绝对不是同一个变量,但地址值是一样的说明该地址绝对不是物理地址、在Linux地址下,这种地址叫做虚拟地址。
那么什么是地址空间?地址空间是是一种数据结构,又操作系统对每一个进程分配一个地址空间,用来管理每个进程执行代码时对物理内存空间的使用。
为什么要有地址空间呢?是因为如果我们直接访问内存空间,有可能会出现野指针,从而写坏别的进程的数据,导致别的进程奔溃。
那么地址空间是如和运行的?首先我们先回答上面刚出现的问题,由于子进程是父进程的一份拷贝,所以子进程的进程物理地址空间和父进程的物理地址空间一样,由于在子进程更改了gar_var变量,而虚拟地址没有发生变化,所以由操作系统在内存重新开辟一块空间用来存储子进程的数据,同使再由操作系统通过页表完成虚拟和物理地址的转换,所以父子进程的地址空间一样但是他们指向内存的地址是不一样的。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值