Linux进程地址空间(一)

文章讲述了Linux系统中进程的地址空间分布,包括虚拟地址和物理地址的概念,以及fork创建子进程时如何保持独立性。通过页表机制,操作系统确保父子进程虽有相同的虚拟地址,但实际物理地址不同,防止数据冲突。此外,还提到了程序编译时的地址分配和vim中多行注释的操作方法。
摘要由CSDN通过智能技术生成

Linux进程地址空间分布

在这里插入图片描述

当我们定义一个全局变量,并且用fork()创建一个子进程,在子进程中改变这个全局变量,我们发现,父子进程,输出地址是一致的,但是变量内容不一样!
能得出如下结论:

变量内容不一样,所以父子进程输出的变量绝对不是同一个变量
但地址值是一样的,说明,该地址绝对不是物理地址!
在Linux地址下,这种地址叫做虚拟地址
我们在用C/C++语言所看到的地址,全部都是虚拟地址!物理地址,用户一概看不到,由OS统一管理,OS必须负责将 虚拟地址 转化成 物理地址 。

当我们用static修饰变量时,其实程序就直接把这个变量放进了全局数据区

进程地址空间

是的,每个进程通常会被分配3GB的虚拟地址空间,而Linux操作系统通常会被分配1GB的虚拟地址空间。在32位的Linux系统中,每个进程能够寻址的最大内存量是4GB,其中1GB被保留给操作系统和内核使用,而3GB被分配给进程使用。因此,每个进程实际上只能够使用3GB的地址空间,而操作系统和内核共享1GB的地址空间。这个1GB的地址空间包括内核代码、内核数据结构、驱动程序和其他操作系统使用的资源等。
需要注意的是,这个1GB的地址空间在每个进程中都是相同的,因为它是由操作系统内核所占用的。每个进程的地址空间是独立的,而操作系统和内核所占用的地址空间是共享的。

那么进程地址空间究竟是什么呢?

首先你要知道,Linux操作系统是需要对每个进程的地址空间进行管理的,那么就需要先描述,而进程地址空间里面有各种各样的区域,那势必要对这些区域进行划分
一个区域划分本质上就是在一个范围内,定义一个start和end
进程地址空间是一种内核级数据结构,里面保存着各个区域的划分,就是一个mm_struct结构体,这个结构体就保存在PCB中

int code_start, code_end;
int stack_start, stack_end;
······

这样对进程地址空间的每个区域管理,就变成了对结构体中的数进行加减
在这里插入图片描述
地址空间和页表是每个进程都私有一份
因此只要做到每个进程的地址空间映射到物理内存的不同区域,那么就可以保证每个进程
不会互相干扰,从而保证进程的独立性。

现在就可以解释最开始的问题了,为什么父子进程的地址一样,同一个变量,但是变量内容却不同
子进程在创建的时候是继承了父进程的大部分内容的,页表也是一样的,但是当子进程去写某个变量时,操作系统会做出检测,这时会在物理内存中给子进程开辟出一段空间,把父进程对应物理内存的内容拷贝过来,同时改变页表的映射关系,其实就是只改变了物理地址那块,所以我们看到的就是虚拟地址一样,但他们映射到的物理地址是不一样的,变量内容自然就不一样。
另外对于fork的两个返回值也是同样
在子进程返回值写入时发生了写时拷贝,同一个变量,地址也一样,但是内容不一样,看起来就是两个返回值。

扩展内容

思考一个问题:当我们的程序在被编译形成可执行程序的时候,还没有被加载到内存的时候,我们的程序内部,有地址吗??
答案是有的
地址空间不要仅仅理解成为是OS内部要遵守的,其实编译器也要遵守,即编译器编译代码的时候,就已经给我们形成了各个区域,代码区,数据区,
并且采用和Linux内核中一样的编址方式,给每一个变量,每一行代码都进行了编址,故,程序在编译的时候,每一个字段早已经具有了一个虚拟地址。
对于地址空间和页表,在程序被从磁盘加载到内存的时候,地址空间直接根据编译器形成的虚拟地址填写自己的start和end,程序被加载到内存之后,每一个变量或语句都有自己的虚拟地址,物理内存中也有他们存放的物理地址,两个地址填入页表,自然就形成了页表里面的映射关系。
CPU执行进程的时候,它拿了变量的虚拟地址,然后通过这个虚拟地址找到页表中对应的物理地址,然后去物理空间访问,取回下一个虚拟地址重复上述过程。
对于CPU来说读到的指令内部,使用的是虚拟地址。
CPU一直拿到的是虚拟地址,它可能并不知道物理地址的存在,仅仅是通过页表来实现转换,访问数据。

补充一个小知识 如何在vim中实现多行选中并且注释

首先按下Esc进入命令模式,按下ctrl+v进入可视化模式,通过 h j k l ,选中某些行,再按下shift+i进入编辑模式,输入注释字符后,按下Esc即可
想要撤销的话,选中后不用进入编辑模式,直接按d即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值