操作系统:进程地址空间

目录

1.程序地址空间

1.1.程序地址空间的介绍

1.2.程序地址空间的本质 

2.进程地址空间

 3.Linux下的地址空间


1.程序地址空间

1.1.程序地址空间的介绍

我们在学习C/C++时,对于各组分的地址分配在程序地址空间的不同模块

如图我们能够验证各组分的对应的地址排布位置,但是我们可以看到堆是向上排布,栈是向下排布这个怎么验证呢? 

所以我们验证了堆的开辟是有下到上,栈的开辟是由上到下,堆栈相对而生,并且我们可以发现堆栈之间有一块大的空白(这也是栈溢出发生的原因)

另外,在栈区中,我们知道地址是由高到低排布的,然而一个整型变量 int a; 由4个字节构成,我们知道一个地址对应着1个字节,那么可以推出int类型实际上由4块连续的地址来实现的,那么int类型在栈上是如何排布的呢?存在两种情况:&a是低地址 或者 高地址

接下来我们看看数组的地址分布

我们看到arr[1]在arr[0]上边,也就是只有地址向上排布时,才能够符合。

那么就有“栈空间的开辟是自上向下,而空间内变量的使用是自下向上增长”

回到对int a的分析

那么以最低地址为起始地址,也就是&a的本质就是这4个字节的最低的那个地址,对于double类型就是8个字节的最低地址,也就是通过 &变量名 + 变量类型 来确定对应变量的地址空间。

换一句话来说:地址空间通过“起始地址+偏移量”来访问不同的变量类型

 讲了这么多,大家也只是知道了程序地址空间,用来存储变量地址的空间

1.2.程序地址空间的本质 

#include <stdio.h>
#include <stdlib.h>
int global_val = 200;
int main()
{pid_t id = fork();if(id<0){printf("fork error\n");return 0;}else if(id == 0){printf("it is child process, pid is: %d , g_val is: %d , g_val_address is: %p \n", getpid(), global_val, &global_val);}else{printf("it is father process, pid is: %d , g_val is: %d , g_val_address is: %p \n", getpid(), global_val, &global_val);}return 0;
}

这里符合我们之前学习的,父子进程在没有对数据写入时,共用一份代码和数据,那么同一个变量也是在同一块地址。

在上述代码的基础上,我们在子进程模块将g_val值修改再来看看!!!

#include <stdio.h>
#include <stdlib.h>
int global_val = 200;
int main()
{pid_t id = fork();if(id<0){printf("fork error\n");return 0;}else if(id == 0){global_val = 100;printf("it is child process, pid is: %d , g_val is: %d , g_val_address is: %p \n", getpid(), global_val, &global_val);}else{printf("it is father process, pid is: %d , g_val is: %d , g_val_address is: %p \n", getpid(), global_val, &global_val);}return 0;
}

与上部分代码相对比,我们发现一个地址,两个变量

我们在学习地址时,每一个物理地址只能对应一个变量,而这里的“0x60104c”却对应着两个不同的g_val的值,所以这个地址一定不是物理地址,而是虚拟地址。

也就是程序地址空间实际上是抽象出来的虚拟地址

我们在之前fork()函数初识时,知道fork()成功调用时的返回值可以为id==0,id>0两个值,本质上就是子进程可以继承父进程的虚拟地址,也就是实际上id就可以看做上面的全局变量global_val,共享一块虚拟地址,那么他们的物理地址呢?这里我们先不多讲剩下的留在下面讲解。

2.进程地址空间

每一个进程运行之后,都会有一个进程地址空间的存在

我们在上面知道,程序地址空间实际上就是抽象出来的虚拟地址,实际上进程地址空间也是抽象出来的虚拟地址。

 因为实际上的数据是存储在物理内存中的,而地址空间是抽象出来的模块,并没有存储数据的能力,也就是地址空间最终需要通过映射关系到物理内存,每一个进程都有一个映射表

实际上父进程在创建子进程后,会和子进程共用同一个物理内存,当父(子)进程数据发生改变时,物理内存中会进行数据的“写时拷贝”,进而产生一块新的地址,并通过页表再映射回去同一个虚拟地址。这就是父子进程的地址空间会出现一个地址对应两个变量的原因,实际上还是两块物理地址。

 3.Linux下的地址空间

地址空间实际上就是一个抽象的模块,连接着进程和物理内存,并且是由操作系统所管理的,那么不就是一个“先描述再组织”结构体吗?

我们发现通过抽象出进程的地址空间这个模块,对于所有的进程均是同一在这个数据块上实现的,并且按照代码中的每一个模块把每一部分都有序地放置在地址空间内,在通过页表映射在物理内存中。那么我们在磁盘中加载程序进入物理内存中时,就可以随意加载在物理内存的任意位置,因为我们只需要通过页表就能进入一个有序的进程地址空间,也可以在维护好的进程地址空间的映射找到对应的物理内存。

这里我们可以看出“地址空间有助于我们将无序的地址变为有序的进程的地址空间的控制”

另外,页表除了存放着虚拟内存和物理内存两个字段外,还存放这一个“物理内存访问权限”字段

除了有访问权限字段,页表中有一个字段用于判断物理内存是否分配,当我们在运行程序时,进程可能处于挂起状态,也就是代码和数据从物理内存放回磁盘中,这时候我们把这个字段的进行修改,表示这个进程不在物理内存中。那么进程在查询页表时发现这个字段为挂起,就能够在进程管理模块中判断该进程为“挂起状态”(进程的状态是进程管理,而挂起实际上是内存层面上的),又因为我们把地址空间和物理内存独立成块了。

所以地址空间的引入,实现了“进程管理和内存管理的解耦!!!”

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

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

相关文章

xss.haozi.me靶场“0x00-0x0A”通关教程

君衍. 一、靶场介绍二、第一关 0x00 不做限制三、第二关 0x01 文本闭合标签绕过四、第三关 0x02 双引号闭合绕过五、第四关 0x03 过滤括号六、第五关 0x04 编码绕过七、第六关 0x05 注释闭合绕过八、第七关 0x06 换行绕过九、第八关 0x07 删除标签十、第九关 0x08 多加空格绕过…

L2-002 链表去重 (25 分)(数组模拟)(附链表相关)

给定一个带整数键值的链表 L&#xff0c;你需要把其中绝对值重复的键值结点删掉。即对每个键值 K&#xff0c;只有第一个绝对值等于 K 的结点被保留。同时&#xff0c;所有被删除的结点须被保存在另一个链表上。例如给定 L 为 21→-15→-15→-7→15&#xff0c;你需要输出去重后…

负数的四舍五入

负数的四舍五入 标签:基础 System.out.println(Math.round(-0.2)); System.out.println(Math.round(-0.5)); System.out.println(Math.round(-0.6));0 0 -1理解:四舍五入,找一个离目标小数近的整数,-0.2和0近,-0.6和-1近,中间的往右靠

力扣每日一题 将标题首字母大写 模拟 String API

Problem: 2129. 将标题首字母大写 文章目录 思路复杂度Code 思路 &#x1f468;‍&#x1f3eb; 灵神题解 复杂度 ⏰ 时间复杂度: O ( n ) O(n) O(n) &#x1f30e; 空间复杂度: O ( n ) O(n) O(n) Code class Solution {public String capitalizeTitle(String title)…

vue3的组件间的v-model参数

v-model 参数 默认情况下&#xff0c;组件上的 v-model 使用 title作为 prop 和 update:title作为事件。我们可以通过向 v-model 传递参数来修改这些名称&#xff1a; zizhi是我自己创建的组件 <zizhi v-model:title"modelValue"></zizhi> 如何让父组件…

重定向、管道与环境变量

前言&#xff1a;测试开发的学习已经开启第三周的学习了。 奋斗至此&#xff0c;内容已稍有难度。 发现每一点都有其深挖的地方&#xff0c;但读书在某些方面来讲要不求甚解&#xff0c;如果只在一点深挖&#xff0c;那可能进度很难提的上来。 继续加油&#xff01;&#xf…

es 分词器详解

基本概念 分词器官方称之为文本分析器&#xff0c;顾名思义&#xff0c;是对文本进行分析处理的一种手段&#xff0c;基本处理逻辑为按照预先制定的分词规则&#xff0c;把原始文档分割成若干更小粒度的词项&#xff0c;粒度大小取决于分词器规则。 分词器发生的时期 1、分词…

实现支持多选的QComboBox

Qt提供的QComboBox只支持下拉列表内容的单选&#xff0c;但通过QComboBox提供的setModel、setView、setLineEdit三个方法&#xff0c;可以对QComboBox进行改造&#xff0c;使其实现下拉列表选项的多选。 QComboBox可以看作两个组件的组合&#xff1a;一个QLineEdit和一个QList…

ctfshow web入门 php特性总结

1.web89 intval函数的利用&#xff0c;intval函数获取变量的整数值&#xff0c;失败时返回0&#xff0c;空的数组返回&#xff0c;非空数组返回1 num[]1 intval ( mixed $var [, int $base 10 ] ) : int Note: 如果 base 是 0&#xff0c;通过检测 var 的格式来决定使用的进…

【工具】Git的介绍与安装

目录 前言 1W&#xff1a;什么是Git&#xff1f; 2W&#xff1a;为什么使用Git&#xff1f; 3W&#xff1a;如何使用Git&#xff1f; Git的安装步骤 测试 3.1 桌面空白部分鼠标右击 3.2 选择 Open Git Bash here 3.3 输入 git -v 命令查看版本 Git区域分布 Git的工作…

软件无线电系列——软件无线电的发展历程及体系框架

本节目录 一、软件无线电的起始 二、软件无线电SDR论坛 三、SPEAKeasy计划 四、JTRS与SCA 五、软件无线电体系框架本节内容 一、软件无线电的起始 1992年5月&#xff0c;美国电信会议上&#xff0c;Joseph Mitola III博士提出来软件无线电(Software Radio,SR)的概念。理想化的…

C语言演示多线程编程条件下自旋锁和屏障的使用

主线故事: 有4个人玩游戏输了,惩罚: 1 分别使用4台不同的ATM机给我存钱 2 必须一块一块的存 3 存完还得在ATM上看一下我的余额 设计模式: 1 每个人使用一条单独的线程,再准备一个计时线程用来输出时间 2 存钱 涉及到 对共享资源的读写,是原子操作需要用锁保护 这里使用自…

windows下安装python virtualenv 虚拟环境

1、首先验证 python 是否安装成功 python -V Python 3.8.2如果出现版本号&#xff0c;表示安装成功了 2、通过 pip 安装 virtualenv pip install virtualenv3、创建虚拟环境 C:\Users\capitek-fengxl> mkvirtualenv blog # 激活虚拟环境 C:\Users\capitek-fengxl> …

SQL 优化实践:关于增强 OceanBase本地索引性能的案例

本文通过一个案例&#xff0c;帮用户了解在Oracle迁移Oceanbase时&#xff0c;应该如何选择全局索引和本地索引以带来更好的SQL性能。 作者&#xff1a;胡呈清&#xff0c;爱可生的DBA团队成员&#xff0c;擅长故障分析和性能优化。本文约 5000 字&#xff0c;预计阅读需要 15 …

GPT实战系列-LangChain实现简单链

GPT实战系列-LangChain实现简单链 LangChain GPT实战系列-LangChain如何构建基通义千问的多工具链 GPT实战系列-构建多参数的自定义LangChain工具 GPT实战系列-通过Basetool构建自定义LangChain工具方法 GPT实战系列-一种构建LangChain自定义Tool工具的简单方法 GPT实战系…

Qt/QML编程之路:fork、vfork、exec、clone的对比及使用(46)

前言: 系统调用system call是OS提供的服务提供接口。系统调用fork()、vfork()、exec()和clone()都用于创建和操作进程。Linux下Qt编程也会用到vfork进行多进程间通信。让我们看一下以下每个系统调用的概述和比较: fork()、vfork()和clone()的工作原理相似,但在处…

「jQuery系列」jQuery DOM操作/尺寸

文章目录 一、jQuery DOM操作元素选择元素创建元素插入元素删除元素复制属性操作文本和 HTML 内容操作CSS 类操作遍历 DOM 二、jQuery 尺寸案例一&#xff1a;获取元素尺寸案例二&#xff1a;设置元素尺寸案例三&#xff1a;使用内外尺寸方法 三、热门文章 一、jQuery DOM操作 …

【Vue】.sync 修饰符作用

文章目录 基本用法 基本用法 官方文档是这样介绍的&#xff1a;.sync 修饰符 简单来说就是实现父子组件数据之间的双向绑定&#xff0c;当子组件修改了一个 props 的值时&#xff0c;也会同步到父组件中&#xff0c;实现子组件同步修改父组件&#xff0c;与v-model类似。类别在…

计算机网络面经八股-什么是 SYN洪泛攻击?如何防范?

SYN洪泛攻击属于 DOS 攻击的一种&#xff0c;它利用 TCP 协议缺陷&#xff0c;通过发送大量的半连接请求&#xff0c;耗费 CPU 和内存资源。 原理&#xff1a; 在三次握手过程中&#xff0c;服务器发送 [SYN/ACK] 包&#xff08;第二个包&#xff09;之后、收到客户端的 [ACK…

狂飙Linux平台,PostgreSQL16部署大全

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…