Linux进程——进程地址空间

news2024/11/18 5:58:28

前言:在讲完环境变量后,相信大家对Linux有更进一步的认识,而Linux进程概念到这也快接近尾声了,现在我们了解Linux进程中的地址空间!


在这里插入图片描述


本篇主要内容:
了解程序地址空间
理解进程地址空间
探究页表和虚拟地址空间

在这里插入图片描述


进程地址空间

  • 1. 程序地址空间
  • 2. 进程地址空间
  • 3. 什么是地址空间
  • 3. 地址空间的管理
  • 4. 页表
  • 5. 为什么要存在地址空间
  • 6. 总结拓展


1. 程序地址空间

我们在学习C语言的时候,大家都了解过这样的空间布局图

在这里插入图片描述
那么到底是不是这样排布的呢,我们来验证一下

    1 #include<stdio.h>
    2 #include<stdlib.h>
    3 
    4 int un_gval;
    5 int init_gval = 100;                         
    6                                      
    7 int main(int argc, char *argv[], char *env[])
    8  {                                            
    9      printf("code addr: %p\n", main);                   
   10      const char *str = "Hello, Linux!";                 
   11      printf("read only char addr: %p\n", str);          
   12      printf("init global value addr: %p\n", &init_gval);
   13      printf("uninit global value addr: %p\n", &un_gval);
   14                                     
   15      char *heap1=(char*)malloc(100);
   16      char *heap2=(char*)malloc(100);
   17      char *heap3=(char*)malloc(100);
   18      char *heap4=(char*)malloc(100);
   19                                        
   20      int a = 100;                      
   21                                        
   22      printf("heap1 addr: %p\n", heap1);
   23      printf("heap2 addr: %p\n", heap2);
   24      printf("heap3 addr: %p\n", heap3);
   25      printf("heap4 addr: %p\n", heap4); 
   26                                         
   27      printf("stack addr: %p\n", &str);  
   28      printf("stack addr: %p\n", &heap1);                                                                                                                                                       29       printf("stack addr: %p\n", &heap2);                                                                                                                                                30       printf("stack addr: %p\n", &heap3);
   31      printf("stack addr: %p\n", &heap4);                                                                                                                                                                  
   32      printf("a addr: %p\n",&a);  
   33      return 0;
   34  }

在这里插入图片描述


栈区中的数组和结构体

int num[10] ......&a[0]  &a[9]

struct s
{
	int a; ......&s.a
	int b; ......&s.b
	int c; ......&s.c
}

在这里插入图片描述

注意:栈区是整体向下增长,局部想上使用的,就是地址最低处,依次往上放后面的元素


但是如果我们将代码更改还能运行过去嘛?

char *str = "Hello, Linux!"; 
*str = 'S';

在这里插入图片描述
显然我们是不能更改的,一更改就就运行不了了

注意:其实是因为字符常量区与代码区很接近,而编译器在编译时,字符常量区就是被编译到代码区的,代码又不可被写入,所以字符常量区也不可被修改

综上:

  • 栈区是整体向下增长,局部想上使用的,就是地址最低处,依次往上放后面的元素
  • 常量区的字符串不允许修改

但是这都是我们之前了解的知识,现在我们来重新了解地址,我们先来看这段代码

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<sys/types.h>
  4 #include<unistd.h>
  5 
  6 int g_val = 200;
  7 
  8 int main()
  9 {
 10     pid_t id = fork();
 11     if(id == 0)
 12     {
 13         // 子进程
 14         int cnt = 5;
 15         while(1)
 16         {
 17             printf("child, pid: %d, ppid: %d, g_val: %d, &g_val: %p\n", getpid(), getppid(), g_val, &g_val);
 18             sleep(1);
 19             if(cnt == 0)
 20             {
 21                 g_val = 100;
 22                 printf("child change g_val: 200 -> 100\n");
 23             }
 24             cnt--;
 25         }
 26         
 27     }
 28     else{
 29         // 父进程
 30         while(1)
 31         {
 32             printf("father, pid: %d, ppid: %d, g_val: %d, &g_val: %p\n", getpid(), getppid(), g_val, &g_val);
 33             sleep(1);                                                                                                                                                                  
 34         }
 35     }
 36     return 0;
 37 }

在这里插入图片描述
我们发现在开始时,输出出来的变量值和地址是一模一样的!
因为我们之前讲过子进程按照父进程为模版,父子并没有对变量进行进行任何修改

但是在达到一定条件之后,父子进程,输出地址是一致的,但是变量内容不一样!

但是相同的地址为什么会有不同的值?

  • 所以我们能得出结论,我们之前看到的地址,绝对不是物理地址,我们平时用到的地址,其实都是虚拟地址/线性地址!
  • 而虚拟地址就是进程地址空间的内容

2. 进程地址空间

我们现在来深入的了解一下为什么相同的的地址为什么会有不同的值?

首先引入一个概念:每一个进程运行之后,都会有一个进程地址空间的存在,在系统层面都要有自己的页表映射结构!
在这里插入图片描述

因此:当一个进程先修改后,它就不再指向原来那块物理空间,而是拥有一个新的物理空间!而页表左边的虚拟空间没有发生改变,所以相同的的地址为什么会有不同的值,是因为映射的物理空间不同!


3. 什么是地址空间

在讲什么是地址空间之前,我们先来讲一个故事,来方便理解!

一个拥有10亿美元身家的富豪,他有4个私生子,每个人都不知道彼此的存在,但是富豪对每个孩子都说,认真做好现在的事,在未来可以继承自己的10个亿家产。

在这里插入图片描述

但是在得到10个亿之前,他的几个孩子,在经济上遇到了问题,前三个都要找富豪要10w美金来解决麻烦,富豪觉得合情合理也就给了,但是它的第四个孩子直接找他要10个亿,富豪当然不能给他,然后讲明原因后给了他20w美金。因此他的所有孩子都可以得到10亿之内的经济资助,但是绝对拿不到10个亿。

在这里插入图片描述

在这个故事中:

  • 操作系统:富豪
  • 内存:10亿美金
  • 进程:私生子
  • 虚拟地址空间:继承10亿的大饼

虚拟地址空间并不是真实的地址


3. 地址空间的管理

富豪给每一个私生子都画了饼,他要把每个私生子都管理起来,也就是要把所有大饼管理起来。

因此:地址空间也要被OS管理起来!!每一个进程都要有地址空间,系统中,一定要对地址空间做管理!!

而操作系统管理地址空间,一定是“先描述,在组织”!地址空间最终一定是一个内核的数据结构对象,
就是一个内核结构体!

在这里插入图片描述
而我们观察进程地址空间,发现里面是一堆的地址划分。
在Linux中,这个描述虚拟地址空间的东西叫做:

struct mm _struct
{
	long code_start;
	long code_end;
	long data_start;
	long data_end;
	long heap_start;
	long heap end; //brk
	long stack _start;
	long stack _end;
	......
}

在这里插入图片描述
而该结构体的大小会被初始化成4gb,线性编程范围从全0到全F,然后把线性范围拆分成细小的范围,这就是地址空间


4. 页表

在上面我们了解到了页表,页表的映射关系中左侧表示虚拟地址,右侧表示物理地址,但是除了这两个其实在页表的映射关系中还存在一个标记字段——访问权限字段

在这里插入图片描述
讲到这里我们再回到字符常量区那里。

char *str = "Hello, Linux!"; 
*str = 'S';

此时我们就可以解释通字符常量区为什么不能修改:

  • 字符常量区在经过页表映射时,访问权限字段只设置成只读的,所以在写入时,页表直接将我们拦住,不让我们访问,所以字符常量区不能修改,代码区也是如此!

所以页表可以进行安全评估,有效的进行进程访问内存的安全检查


在除去上面提到的东西以外,页表还可以通过二进制衡量能存中有没有内容,是否分配地址

在这里插入图片描述
当我们有个虚拟地址要被访问了,但是它并没有被分配空间,更不会有内容,那该则么办呢?
在这里插入图片描述

其实在这个时候操作系统会将你的这个访问暂停,然后进行一下操作:

  • 操作系统会将你的可执行程序重新开辟空间
  • 把对应可执行程序需要执行的这个虚拟地址对应的代码加载到内存里
  • 把对应的虚拟地址填充到页表
  • 把标志位改为1,代表已经分配地址,且内容已经填充
  • 将暂停的代码继续访问

操作过程也称为缺页中断

而我们操作系统在进行这些工作时,是在进行内存管理, 而进程管理和内存管理因为有了地址空间的存在 ,实现了在操作系统层面上的模块的解耦!


5. 为什么要存在地址空间

到了这里我想大家也都了解得差不多了,为什么要存在地址空间,原因有很多

一、 让无序便有序

  • 让进程以统一的视角看待内存
  • 在页表层映射时会将不同的数据类型进行划分使得映射到物理内存后是比较有序的一种状态!
  • 所以任意一个进程,可以通过地址空间+页表可以将乱序的内存数据,变成有序,分门别类的规划好!

二、存在虚拟地址空间,可以有效的进行进程访问内存的安全检查

三、将进程管理和内存管理进行解耦

四、保证进程的独立性

通过页表让进程虽然虚拟地址一样但是映射到不同的物理内存处,从而实现进程的独立性

6. 总结拓展

拓展:
在mm_struct中还会存在一个struct vm_area_struct的结构 ,它能划分出一个start,一个end。如果我们还想继续划分就会有多个struct vm_area_struct的结构,然后他们会构成一个线性划分的链表结构。

struct vm_area_struct
{
	struct mm_struct * vm_mm;
	unsigned long vm_start;
	unsigned long vm_end;
	......
}

到这里我们的进程地址空间也接近尾声了,地址空间让进程管理和内存管理互不干涉,起到了很大作用。结束进程地址空间,我们的Linux进程概念到这里也结束了,后面我将带大家走进进程控制。

谢谢大家支持本篇到这里就结束了

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1664327.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ChatGPT 即将登陆 iPhone;斯坦福推出 AI 辅助全息成像技术丨 RTE 开发者日报 Vol.202

开发者朋友们大家好&#xff1a; 这里是 「RTE 开发者日报」 &#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE&#xff08;Real Time Engagement&#xff09; 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文…

【优选算法】——Leetcode——LCR 179. 查找总价格为目标值的两个商品

1.题目 2. 解法⼀&#xff08;暴⼒解法&#xff0c;会超时&#xff09;&#xff1a; 1.算法思路&#xff1a; 2.图解 3. 代码实现 3. 解法⼆&#xff08;双指针-对撞指针&#xff09;&#xff1a; 1.算法思路&#xff1a; 2.图解 3.代码实现 1.C语言 2…

4G,5G执法记录仪人脸识别、人脸比对使用说明

4G/5G执法记录仪或4G/5G智能安全帽&#xff0c;做前端人脸识别、人脸比对&#xff0c;采用了上市公司的成熟的人脸识别算法&#xff0c;需要支付LICENSE给算法公司&#xff0c;理论上前端设备支持30K的人脸库&#xff08;受设备运行内存限制&#xff09;。 4G/5G执法记录仪侧要…

1.前端环境搭建

1.安装nodejs 因为我们开发Vue项目需要使用npm命令来创建和启动&#xff0c;安装node.js是为了获得这个命令&#xff0c;目前和使用node.js无关 下载地址&#xff1a;http://nodejs.cn/download/ 下载完之后安装&#xff0c;通过cmd查看是否安装成功 node --version2.创建项目…

使用./build.sh编译ORB_SLAM源码时出现报错:/usr/bin/ld:找不到 -lboost_serialization的解决办法

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、/usr/bin/ld:找不到 -lboost_serialization1.问题描述2.解决(1). 下载源码(2) . 编译安装 一、/usr/bin/ld:找不到 -lboost_serialization 1.问题描述 在安装…

KAN核心团队震撼力作!MIT华人用AI首次发现物理学全新方程 | 最新快讯

新智元报道 编辑&#xff1a;Aeneas 好困 刚刚提出了 KAN 的 MIT 物理学家 Max Tegmark 和北大校友刘子鸣&#xff0c;又有一项重磅研究问世了&#xff01;团队发现&#xff0c;它们用 AI 发现了物理学中的新方程&#xff0c;从此&#xff0c;AI 很可能被引入物理学研究领域&am…

IPv6资产测绘哪家强?揭秘新一代网络空间资产测绘平台的独门秘籍

网络空间资产测绘&#xff0c;即通过一系列技术手段&#xff0c;对网络中的各类资产进行全面的发现、分类和定位&#xff0c;为各类用户提供精准的数据支撑和决策依据。网络空间资产测绘作为一门新兴的交叉学科&#xff0c;融合了计算机网络技术、数据挖掘、人工智能、信息安全…

Docker学习笔记(一)安装Docker、镜像操作、容器操作、数据卷操作

文章目录 1 Docker介绍1.1 Docker的优势1.1.1 应用部署的环境问题1.1.2 Docker解决依赖兼容问题1.1.3 Docker解决操作系统环境差异1.1.4 小结 1.2 Docker和虚拟机的区别1.3 Docker架构1.3.1 镜像和容器1.3.2 DockerHub1.3.3 Docker架构 1.4 安装Docker1.4.1 卸载旧版本Docker&a…

【微信开发】微信支付前期准备工作(申请及配置)

1、申请并配置公众号或微信小程序 1.1 账户申请 通过微信公众平台&#xff0c;根据指引申请微信小程序或公众号&#xff0c;申请时需要微信认证&#xff0c;申请流程不在赘述 1.2 信息配置 申请通过后&#xff0c;需进入小程序和公众号内进行信息配置 1.2.1 小程序信息配置…

小程序地理位置接口申请教程来啦4步学会

小程序地理位置接口有什么功能&#xff1f; 如果我们提审后驳回理由写了“当前提审小程序代码包中地理位置相关接口( chooseAddress、getLocation )暂未开通&#xff0c;建议完成接口开通后或移除接口相关内容后再进行后续版本提审”&#xff0c;如果你也碰到类似问题&#xff…

任务:单域,域树的搭建

一、单域&#xff1a; 搭建所需的系统&#xff1a;win2016 sever&#xff0c;win10 1.在创建域前&#xff0c;先设置静态ip 先查看win2016 sever的IP&#xff0c; ip&#xff1a;192.168.154.133 网关&#xff1a;192.168.154.2 DNS服务器&#xff1a;192.168.154.2 设置…

FPGA学习笔记(1)——Vivado和HLS

1 Vivado设计 1.1 FPGA基本知识 Xilinx Atrix-7使用6输入LUT结构&#xff08;0-63&#xff09;CLB&#xff1a;可配置逻辑块Slice&#xff1a;每个CLB包含2个Slice(包含查找表LUT和8位寄存器REG)布线池&#xff1a;围绕在CLB周围&#xff0c;衔接FPGA的资源调度I/O块&#xf…

conan2 基础入门(02)-安装

conan2 基础入门(02)-安装 文章目录 conan2 基础入门(02)-安装⭐前言⭐安装python安装安装包安装自行操作 ⭐验证配置环境变量命令行验证conan配置文件 END ⭐前言 Conan 2.0: C and C Open Source Package Manager 官方提供三种安装conan的方式。分别为&#xff1a; Recommen…

vuex核心概念-getters

除了state之外&#xff0c;有时我们还需要从state中派生出一些状态&#xff0c;这些状态是依赖state的&#xff0c;此时会用到getters。

鸿蒙内核源码分析(远程登录篇) | 内核如何接待远方的客人

什么是远程登录? 每个人都有上门做客的经历,抖音也一直在教我们做人,做客不要空手去,总得带点东西,而对中国人你就不能送钟,不能送梨,最好也别送鞋,因他们与 终 离 邪 谐音,犯忌讳. 这是人情世故,叫礼仪,是中华文明圈的共识,是相互交流信任的基础. 那互联网圈有没有这种共识呢…

光伏无人机巡检都有哪些功能?

随着光伏产业的快速发展&#xff0c;光伏电站的巡检工作变得越来越重要。然而&#xff0c;传统的人工巡检方式面临着效率低下、安全隐患大等问题。为了应对这些挑战&#xff0c;光伏无人机巡检应运而生&#xff0c;以其独特的优势在光伏巡检领域发挥着越来越重要的作用。本文将…

OpenCv中cv2.subtract(image,blurred)与(image-blurred)的区别

目录 一、cv2.subtract()函数二、cv2.subtract(image,blurred)和&#xff08;image-blurred&#xff09;处理效果对比2.1 代码2.2 输出结果 三、总结 一、cv2.subtract()函数 cv2.subtract是OpenCV库中的一个函数&#xff0c;用于进行图像减法运算。它可以很方便地进行两个图像…

力扣刷题--数组--第一天

一、数组 数组特点&#xff1a; 连续内存空间存储得数据元素类型一致数组可以通过下标索引查找数据元素&#xff0c;可以删除、替换、添加元素等 1.1 二分查找 使用二分查找需满足得条件&#xff1a; 数组是有序的&#xff1b;数组中没有重复元素&#xff1b;查找的target…

三层交换机与路由器连通上网实验

三层交换机是一种网络交换机&#xff0c;可以实现基于IP地址的高效数据转发和路由功能&#xff0c;通常用于大型企业、数据中心和校园网络等场景。此外&#xff0c;三层交换机还支持多种路由协议&#xff08;如OSPF、BGP等&#xff09;&#xff0c;以实现更为复杂的网络拓扑结构…

同程旅行基于Proxy的Kafka最佳实践

公众号文章&#xff1a;同程旅行基于Proxy的Kafka最佳实践 Apache Kafka&#xff0c;作为当前企业级数据流处理的首选平台&#xff0c;由于其高吞吐量和可扩展性而深受欢迎。 然而&#xff0c;随着企业数据量的爆炸性增长和业务需求的多样化&#xff0c;Kafka 集群面临着各种挑…