【Linux】深挖进程地址空间
> 作者简介:დ旧言~,目前大二,现在学习Java,c,c++,Python等
> 座右铭:松树千年终是朽,槿花一日自为荣。> 目标:熟悉【Linux】进程地址空间
> 毒鸡汤:也许有一天,你发觉日子特别的艰难,那可能是这次的收获特别的巨大。
> 望小伙伴们点赞👍收藏✨加关注哟💕💕
🌟前言
学习每一个语言都跟地址扯不开关系,这也是学习每一种语言的必修课,学习好地址空间对语言的掌握熟练度就是质的飞越,我们学习代码知识只是语言的表面,像地址空间就比较深层,有点抽象,不好理解,基于这种情况博主给大家带来【Linux】深挖进程地址空间。
⭐主体
我们从以下学习【Linux】深挖进程地址空间😋😋。
简单来讲就是是什么,为什么,怎么做😜😜。
🌙什么是进程地址空间
再次回顾 C/C++ 学习地址空间时候:
地址空间是什么?是内存么?我们举个栗子:
代码如下:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <assert.h>int g_val = 100;
int main()
{pid_t id = fork();assert(id >= 0);if (id == 0) {while (1){printf("我是子进程,我的id是:%d,我的父进程是:%d,g_val:%d,&g_val:%p\n", getpid(), getppid(), g_val, &g_val);sleep(1);g_val = 200;}}else{while (1){printf("我是父进程,我的id是:%d,我的父进程是:%d, g_val: %d, &g_val: %p\n", getpid(), getppid(), g_val, &g_val);sleep(1);}}return 0;
}
运行结果:
通过上图可以发现子进程的g_val修改成了200,但是父进程的g_val始终未改变的。
- 我们的fork调用之后创建了一个子进程,父子进程的代码和数据共享,而进程是具有独立性的
- 所以改变子进程的g_val的值并不会影响父进程的g_val,这是得益于fork函数采用了写实拷贝的方法实现的
最大的问题是父子进程的地址相同,对应的g_val值竟然不一样?同一块空间有两个不同的值??
- 这块空间绝不是物理地址(内存),因为物理地址(内存)对应的内容肯定是唯一的!!
- 不可能会出现同一个变量的地址读取出两个不同的值。
这里的地址实际上是虚拟地址(线性地址),Linux也有可能叫做逻辑地址。
虚拟空间:所以对于我们而言,直接使用虚拟地址,操作系统再从虚拟地址到页表加载到内存,在通过页表映射,找到对应的物理内存。也就是说,操作系统自动完成。
采用图解的方式:
- 父进程和子进程都有自己的独立的进程地址空间,且都有自己的页表结构。
- 子进程由父进程创建,所以子进程的地址空间是从父进程拷贝而来,刚开始的g_val经过映射指向同一个物理内存,所以刚开始看到的都是100。
后来子进程修改了自己地址空间的g_val的值,当操作系统通过页表映射发现g_val的值是共享的,但是我们知道进程具有独立性,所以操作系统为了保证进程的独立性,当子进程或者父进程任何一方尝试对共享数据进行写入,那么操作系统会在物理内存上重新开辟一块新的内存空间,拷贝数据,然后在修改映射关系,不再指向老的变量,在整个修改的过程中,和父子进程的虚拟地址没有任何关系,只是底层经过页表映射到不同的区域,所以我们看到了地址是一样的,但是内容却是不一样的,这就是现象的由来!
如何理解线性地址?
以32位计算机为例,我们有32根地址线,每根地址线对应的数据只有0 1信号,那么32根地址线就有2^32中排列组合,就有2^32个地址,我们的CPU在运算完某些数据之后,会进行寻址找到一段地址空间将其存放在内存中,内存地址中最小的单位为字节,那么2^32个地址占据2^32个字节空间,换算出来总的地址空间大小就是4GB!!因为我们的地址是按照字节号大小依次递增的,所以我们就认为地址空间是一个线性结构。
🌙为什么要虚拟地址空间
- 进程地址空间保证了数据的安全性。
每个进程都有进程地址空间,所有的进程都要通过页表映射到物理内存,如果进程直接访问物理内存,万一进程越界非法访问、非法读写时,页表就可以进行拦截,而且直接访问物理内存对于账号信息是非常不安全的,所以保证了内存数据的安全性。
- 地址空间的存在,可以更方便的进行进程和进程的数据代码的解耦,保证了进程独立性的特征
对于进程而言,都有独立的地址空间及页表,通过页表映射到不同的物理内存上,所以一个进程数据的改变不会影响到另一个进程,保证了进程的独立性,而对于上面我们所说的父进程和子进程而言,子进程的地址空间从父进程拷贝,页表都指向同一块物理内存,但是即使此时的数据是共享的,在修改数据的时候也会发生我们所说的写时拷贝,保证了进程的独立性
- 让进程以统一的视角,看待进程对应的代码和数据各个区域,方便编译器也以统一的视角来进行编译代码。
可执行程序被编译器编译的时候每个代码和数据在内存中已经有虚拟地址了(在磁盘上称为逻辑地址),也就是说,地址空间对于操作系统和编译器都是遵守的。所以当程序被加载到内存成为进程后,每个变量/函数都具备了物理地址。
所以我们现在有两套地址:
- 标识物理内存中代码和数据的地址
- 在程序内部互相跳转的时候的虚拟地址
加载完成之后,代码的各个区域的地址已经知道。进程被调度时,CPU拿到虚拟地址,经过地址空间查页表通过映射,进行访问查到物理地址往后执行。也就是CPU通过了虚拟地址——页表映射——物理地址执行。也就是在整个CPU运行过程中,CPU并没有见到物理地址,用的都是虚拟地址。
另外,对于磁盘内可执行程序编译好,这个可执行程序的地址不叫虚拟地址,是逻辑地址。但是对于Linux而言,虚拟地址、线性地址、逻辑地址都是一样的。
🌙虚拟地址与物理地址如何联系
fork在返回时,父子进程都已经创建好了,这两个进程是独立的,是不是就会return两次?返回的本质是不是写入?谁先return谁就先进行写实拷贝,同一块地址是子进程继承父进程的虚拟地址,return返回写入后,它们就映射到不同的物理空间上了。
🌟结束语
今天内容就到这里啦,时间过得很快,大家沉下心来好好学习,会有一定的收获的,大家多多坚持,嘻嘻,成功路上注定孤独,因为坚持的人不多。那请大家举起自己的小手给博主一键三连,有你们的支持是我最大的动力💞💞💞,回见。
相关文章:

【Linux】深挖进程地址空间
> 作者简介:დ旧言~,目前大二,现在学习Java,c,c,Python等 > 座右铭:松树千年终是朽,槿花一日自为荣。 > 目标:熟悉【Linux】进程地址空间 > 毒鸡汤ÿ…...

SVM(支持向量机)-机器学习
支持向量机(Support Vector Machine,SVM)是一种用于分类和回归分析的监督学习算法。它属于机器学习中的一类强大而灵活的模型,广泛应用于模式识别、图像分类、自然语言处理等领域。 基本原理: SVM的基本原理是通过找到能够有效分…...
解决生成的insert语句内有单引号的情况
背景 因为Mybatis-Plus的saveBatch()方法的批量插入其实也是循环插入,而不是真正的一个SqlSession完成的批插,效率很低。所以我们在写批量插入的时候是自己实现了一个工具类去生成批量插入的sql再去执行,但是会遇到有些文本里有单引号导致插…...
【Linux 程序】1. 程序构建
文章目录 【 1. 配置 】【 2. 编译 】makefile编写的要点makefile中的全局自变量CMake编译依赖的库g编译 【 3. 安装 】 一般源代码提供的程序安装需要通过配置、编译、安装三个步骤; 配置。检查当前环境是否满足要安装软件的依赖关系,以及设置程序安装所…...

GLTF 编辑器实现逼真3D动物毛发效果
在线工具推荐: 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 要实现逼真的3D动物毛发效果,可以采用以下技术和方法&…...
【Go语言入门:Go语言的方法,函数,接口】
文章目录 4.Go语言的方法,函数,接口4.1. 方法4.1.1. 指针接受者4.1.2. 值接收者和指针接收者有什么区别?4.1.3. 方法 4.2. 接口4.2.1. 接口定义 4.3. 函数4.3.1. 函数介绍 4.Go语言的方法,函数,接口 4.1. 方法 4.1.1…...

vue-cli3/webpack打包时去掉console.log调试信息
文章目录 前言一、terser-webpack-plugin是什么?二、使用配置vue-cli项目 前言 开发环境下,console.log调试信息,有助于我们找到错误,但在生产环境,不需要console.log打印调试信息,所以打包时需要将consol…...

企业品牌推广在国外媒体投放的意义和作用何在?
海外广告投放是企业在国际市场推广的重要战略,具有多种形式,包括社交媒体广告、短视频广告、电视广告等。这些广告形式在传播信息、推动销售、塑造品牌形象等方面发挥着独特的作用。 其中软文发稿是一种注重叙事和信息传递的广告形式,对于企…...

ArcGIS批量计算shp面积并导出shp数据总面积(建模法)
在处理shp数据时, 又是我们需要知道许多个shp字段的批量计算,例如计算shp的总面积、面积平均值等,但是单个查看shp文件的属性进行汇总过于繁琐,因此可以借助建模批处理来计算。 首先准备数据:一个含有多个shp的文件夹。…...

代码质量评价及设计原则
1.评价代码质量的标准 1.1 可维护性 可维护性强的代码指的是: 在不去破坏原有的代码设计以及不引入新的BUG的前提下,能够快速的修改或者新增代码. 不易维护的代码指的是: 在添加或者修改一些功能逻辑的时候,存在极大的引入新的BUG的风险,并且需要花费的时间也很长. 代码可…...
编程笔记 html5cssjs 012 HTML分块
编程笔记 html5&css&js 012 HTML分块 一、HTML 块级元素二、HTML 内联元素三、HTML <div> 元素四、HTML <span> 元素五、HTML<article>元素六、<article>元素和<div>元素的区别与联系小结 像报纸排版一样,很多时候需要把平面…...

【持续更新ing】uniapp+springboot实现个人备忘录系统【前后端分离】
目录 (1)项目可行性分析 (2)需求描述 (3)界面原型 (4)数据库设计 (5)后端工程 接下来我们使用uniappspringboot实现一个简单的前后端分离的小项目----个…...

nginx+rsyslog+kafka+clickhouse+grafana 实现nginx 网关监控
需求 我想做一个类似腾讯云网关日志最终以仪表方式呈现,比如说qps、p99、p95的请求响应时间等等 流程图 数据流转就像标题 nginx ----> rsyslog ----> kafka —> clickhouse —> grafana 部署 kafka kafka 相关部署这里不做赘述,只要创…...
User maven 通过什么命令能查到那个包依赖了slf4j-simple-1.7.36.jar
要在 Maven 项目中查找哪个包依赖了 slf4j-simple-1.7.36.jar,您可以使用 Maven 的依赖树命令 mvn dependency:tree。这个命令会展示项目所有依赖的层次结构,包括传递依赖(即一个依赖的依赖)。然后,您可以搜索或过滤输…...

什么牌子冻干猫粮性价比高?性价比高的五款冻干猫粮牌子推荐
很多养猫的小伙伴们都磨刀霍霍准备给猫咪屯些猫冻干吧,特别是家里有挑食猫咪的家庭。有养猫的铲屎官们应该都知道,猫咪是对蛋白质的需求量很高,而且对植物蛋白的吸收效率比较低,所以蛋白质最好都是来自动物的优质蛋白。猫咪挑食就…...

扫描全能王启动鸿蒙原生应用开发,系HarmonyOS NEXT智能扫描领域首批
近期,“鸿蒙合作签约暨扫描全能王鸿蒙原生应用开发启动仪式”(简称“签约仪式”)正式举行。合合信息与华为达成鸿蒙合作,旗下扫描全能王将基于HarmonyOS NEXT正式启动鸿蒙原生应用开发。据悉,扫描全能王是鸿蒙在智能扫…...

[Angular] 笔记 8:list/detail 页面以及@Input
1. list 页面 list/detail 是重要的 UI 设计模式。 vscode terminal 运行如下命令生成 detail 组件: PS D:\Angular\my-app> ng generate component pokemon-base/pokemon-detail --modulepokemon-base/pokemon-base.module.ts CREATE src/app/pokemon-base/p…...

Zabbix“专家坐诊”第221期问答汇总
问题一 Q:使用官方docker模板Template App Docker,监控docker镜像,有一项监控项docker.data_usage有报错,不知道哪里问题:Cannot fetch data: Get “http://1.28/system/df”: context deadline exceeded (Client.Time…...

Netty—Reactor线程模型详解
文章目录 前言线程模型基本介绍线程模型分类Reactor线程模型介绍Netty线程模型: 传统阻塞IO的缺点Reactor线程模型单Reactor单线程模式单Reactor多线程模式主从Reactor多线程Reactor 模式小结 Netty 线程模型案例说明:Netty核心组件简介ChannelPipeline与…...

开源verilog模拟 iverilog verilator +gtkwave仿真及一点区别
开源的 iverilog verilator 和商业软件动不动几G几十G相比,体积小的几乎可以忽略不计。 两个都比较好用,各有优势。 iverilog兼容性好。 verilator速度快。 配上gtkwave 看波形,仿真工具基本就齐了。 说下基本用法 计数器 counter.v module…...

定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...

Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...
什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南
文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果
sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分: 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...

华为OD机试-最短木板长度-二分法(A卷,100分)
此题是一个最大化最小值的典型例题, 因为搜索范围是有界的,上界最大木板长度补充的全部木料长度,下界最小木板长度; 即left0,right10^6; 我们可以设置一个候选值x(mid),将木板的长度全部都补充到x,如果成功…...
【安全篇】金刚不坏之身:整合 Spring Security + JWT 实现无状态认证与授权
摘要 本文是《Spring Boot 实战派》系列的第四篇。我们将直面所有 Web 应用都无法回避的核心问题:安全。文章将详细阐述认证(Authentication) 与授权(Authorization的核心概念,对比传统 Session-Cookie 与现代 JWT(JS…...

C# winform教程(二)----checkbox
一、作用 提供一个用户选择或者不选的状态,这是一个可以多选的控件。 二、属性 其实功能大差不差,除了特殊的几个外,与button基本相同,所有说几个独有的 checkbox属性 名称内容含义appearance控件外观可以变成按钮形状checkali…...