【linux进程(七)】程序地址空间深度剖析

简介: 【linux进程(七)】程序地址空间深度剖析

1. 前言

由于此Linux系列文章偏向于做

顺序学习手册,所以有些内容在

一篇文章中可能不连贯,敬请谅解!

请先阅读下面的文章的最后一段
了解打印出来的地址并不是物理地址
这一事实逻辑:

程序地址空间前言

本章重点:

本篇文章着重讲解进程中的虚拟地址
和物理地址的关系,了解虚拟地址的
内核本质是什么,以及页表和物理地址
的映射逻辑和写时拷贝的具体体现,
期间我们将回答三个问题:

  • 什么是地址空间?
  • 地址空间是如何设计的?
  • 为什么要有地址空间?

2. 什么是程序地址空间?

在理解地址空间前,我们知道一个事实:

平时看见的地址并不是真实的地址

又叫虚拟地址,真实的地址空间

被称为物理地址(物理内存)

我想通过讲一个故事来帮助理解
到底什么是程序地址空间:

有一个富豪,它有10亿资产,由于
年轻时比较浪,所以他有四个私生子
这四个私生子并不知道彼此的存在,
私生子A是个医生,私生子B是个企业家
私生子C是个街头混混,私生子D是个学生
富豪分别对小A,B,C,D说:
(1),小A啊,你要是努力做个医生,以后我的
10亿美金都是你的了
(2),小B啊,要是你把你的公司运作的很好
以后我的10亿美金就是你的了
(3),小C啊…小D啊…

故事还没结束,有一天,A说:老爸
给我10万美金,我要买医疗器械,
富豪想了想觉得是正事,于是给了
小A十万美金,小C又说:老爸,给我
两千美金吧,我吃不起饭了,富豪一听
就把钱打过去了,所以我们知道,这四个
人都可以用10亿美金以内的钱,但是
永远用不到10亿美金!

现在列出人物和地址的对应关系:

  1. 富豪对应操作系统
  2. 10亿美金对应物理地址
  3. 私生子对应每一个进程
  4. 富豪画的饼对应地址空间

所以可以得出结论,地址空间可以
理解为操作系统给进程画的饼
它并不是真实的物理地址!


3. 程序地址空间是如何设计的?

既然富豪给每一个私生子都画了饼
所以对应每一个进程都又一个自己的
程序地址空间,这是第一个结论

然而,OS要管理这些空间,一定
要先组织,再管理!所以地址空间
是一个struct结构,**这是第二个结论**

再来看看程序地址空间的图:

程序地址空间无非就是各个
区域的结合,然而各个区域的划分
无非就是两个整数begin和end
一个在区域的开头,一个在区域的结尾
这是第三个结论!
如图:

根据上面的推论,我们可以得出结论:
地址空间这个北河数据结构中(struct)
至少包含了各个区域的划分,它的概念
结构如下:

struct addr_room
{
  int code_start;//代码区起始
  int code_end;//代码区结束
  int init_start;//初始化区起始
  int init_end;//初始化区结束
  int heap_start;//堆区起始
  int heap_end;//堆区结束
  ......
  其他属性
};

所谓的区域范围变化
实际上就是对start和end做加减!


4. 虚拟地址和物理地址的关联

当我们理解了什么是虚拟地址后,

现在再谈虚拟地址和物理地址的关系:

本质是一种映射关系!

现代计算机使用以下方法解决问题:
OS为每一个进程配对一个虚拟地址
空间和一张页表,要访问物理地址时,
需要先在页表进行映射,若访问的是
非法地址,则会在页表层阻止你的访问!

所以为什么一个地址会有两个值?

现在我们就能回答这个问题了:

创建子进程时,子进程的数据和
代码和父进程共享,也就是和父进程
一样,所以此时子进程的页表和程序
地址空间和父进程一样!当子进程尝试
修改变量的值时,操作系统会重新为子进程
开辟一份物理内存,并修改子进程页表的
映射关系,此时映射到物理内存的不同
区域,但是虚拟地址是一样的!

这个过程也叫写时拷贝


5. 页表的结构以及作用

修改常量字符串时编译器会报错,

是在哪个阶段报的错呢?

const char* p = "abcd";
*p = "123";

其实页表不仅仅只有映射关系

表这一个结构,它还附带了物理
内存中每一个区域的读写权限:

很明显,常量字符串对应的物理地址
区域的权限是只可读,所以当虚拟内存
去映射物理内存时,在页表层面发现你的
访问是权限不允许的,就会在页表层驳回
你的请求,也就是会报错!

所以页表可以起到安全评估

保护物理内存的作用!

这是页表的第一个作用

页表的第二个作用:

将无序变有序

虚拟地址在映射物理内存时
是不是随意映射的?就是说映射
到物理内存后的顺序是全乱的?
结论是当然不是!在页表层映射时
会将不同的数据类型进行划分
使得映射到物理内存后是比较
有序的一种状态!


6. 为什么要存在地址空间?

通过以下三个方面来说明

地址空间的作用:

  1. 有效的保护了物理内存

凡是非法的访问或者映射,os都
会识别到,并且终止你这个进程!
地址空间和页表都由OS创建并
进行管理,一切访问都要在OS的监管下!

  1. 使OS的耦合度更低

因为有地址空间和页表的存在,
物理内存可以不关心未来数据的
类型,可以直接对它进行加载,这样
物理内存的分配就可以和进程的管理
分开来,做到它们并没有任何关系,
所以内存管理模块和进程管理模块
就完成了解耦合的操作!

  1. 保证进程的独立性

因为有地址空间的存在,每一个进程
都认为自己拥有4GB的空间,并且各个
区域是有序的,进而可以通过页表映射
到不同的区域,来实现进程的独立性,
每一个进程不知道也不需要知道其他
进程的存在!!!


7. 总结以及拓展

关于Linux进程基础的内容就讲到

这里,下一章是全新的章节–进程控制

讲了这么久的理论了,怎么控制一个进程?

也就是创建,回收一个进程?有了前面

的基础铺垫后,后面的学习内容也就容易了

拓展阅读:

Linux中页表的内核代码


🔎 下期预告:Linux进程控制 🔍


相关文章
|
监控 Shell Linux
Linux进程控制(详细讲解)
进程等待是系统通过调用特定的接口(如waitwaitpid)来实现的。来进行对子进程状态检测与回收的功能。
408 0
|
存储 负载均衡 算法
Linux2.6内核进程调度队列
本篇文章是Linux进程系列中的最后一篇文章,本来是想放在上一篇文章的结尾的,但是想了想还是单独写一篇文章吧,虽然说这部分内容是比较难的,所有一般来说是简单的提及带过的,但是为了让大家对进程有更深的理解与认识,还是看了一些别人的文章,然后学习了学习,然后对此做了总结,尽可能详细的介绍明白。最后推荐一篇文章Linux的进程优先级 NI 和 PR - 简书。
462 0
|
存储 Linux Shell
Linux进程概念-详细版(二)
在Linux进程概念-详细版(一)中我们解释了什么是进程,以及进程的各种状态,已经对进程有了一定的认识,那么这篇文章将会继续补全上篇文章剩余没有说到的,进程优先级,环境变量,程序地址空间,进程地址空间,以及调度队列。
335 0
|
Linux 调度 C语言
Linux进程概念-详细版(一)
子进程与父进程代码共享,其子进程直接用父进程的代码,其自己本身无代码,所以子进程无法改动代码,平时所说的修改是修改的数据。为什么要创建子进程:为了让其父子进程执行不同的代码块。子进程的数据相对于父进程是会进行写时拷贝(COW)。
427 0
|
Linux
linux中将程序加入到开机自动启动
如果将在linux中将命令或者程序设置为开机自动启动,只需要进入到将对应命令加入到/etc/rc.d/rc.local文件里即可,如下 打开文件,vi /etc/rc.d/rc.local   #!/bin/sh## This script will be executed *after* all the other init scripts.
1605 0
|
Linux 应用服务中间件 Shell
二、Linux文本处理与文件操作核心命令
熟悉了Linux的基本“行走”后,就该拿起真正的“工具”干活了。用grep这个“放大镜”在文件里搜索内容,用find这个“探测器”在系统中寻找文件,再用tar把东西打包带走。最关键的是要学会使用管道符|,它像一条流水线,能把这些命令串联起来,让简单工具组合出强大的功能,比如 ps -ef | grep 'nginx' 就能快速找出nginx进程。
1132 1
二、Linux文本处理与文件操作核心命令
linux命令—stat
`stat` 是 Linux 系统中用于查看文件或文件系统详细状态信息的命令。相比 `ls -l`,它提供更全面的信息,包括文件大小、权限、所有者、时间戳(最后访问、修改、状态变更时间)、inode 号、设备信息等。其常用选项包括 `-f` 查看文件系统状态、`-t` 以简洁格式输出、`-L` 跟踪符号链接,以及 `-c` 或 `--format` 自定义输出格式。通过这些选项,用户可以灵活获取所需信息,适用于系统调试、权限检查、磁盘管理等场景。
839 137
|
安全 Ubuntu Unix
一、初识 Linux 与基本命令
玩转Linux命令行,就像探索一座新城市。首先要熟悉它的“地图”,也就是/根目录下/etc(放配置)、/home(住家)这些核心区域。然后掌握几个“生存口令”:用ls看周围,cd去别处,mkdir建新房,cp/mv搬东西,再用cat或tail看文件内容。最后,别忘了随时按Tab键,它能帮你自动补全命令和路径,是提高效率的第一神器。
1812 58
|
存储 安全 Linux
Linux卡在emergency mode怎么办?xfs_repair 命令轻松解决
Linux虚拟机遇紧急模式?别慌!多因磁盘挂载失败。本文教你通过日志定位问题,用`xfs_repair`等工具修复文件系统,三步快速恢复。掌握查日志、修磁盘、验重启,轻松应对紧急模式,保障系统稳定运行。
1740 2
|
Unix Linux 程序员
Linux文本搜索工具grep命令使用指南
以上就是对Linux环境下强大工具 `grep` 的基础到进阶功能介绍。它不仅能够执行简单文字查询任务还能够处理复杂文字处理任务,并且支持强大而灵活地正则表达规范来增加查询精度与效率。无论您是程序员、数据分析师还是系统管理员,在日常工作中熟练运用该命令都将极大提升您处理和分析数据效率。
993 16