【Linux】程序地址空间
程序地址空间
- 首先引入地址空间的作用
- 什么是地址空间
- 为什么要有地址空间
首先引入地址空间的作用
1 #include <stdio.h>2 #include <unistd.h>3 #include <stdlib.h>4 int g_val = 100;6 int main()7 {8 pid_t id = fork();9 if(id == 0)10 {11 int cnt = 0;12 while(1)13 {14 printf("I am child,pid : %d,ppid : %d,g_val : %d,&g_val : %p\n",getpid(),getppid(),g_val,&g_val);15 cnt++;16 sleep(1);17 if(cnt == 5)18 {19 g_val = 200;20 printf("child chage g_val 100 -> 200 success\n");21 }22 }23 }24 else 25 {26 //father27 while(1)28 { 29 30 printf("I am father,pid : %d,ppid : %d,g_val : %d,&g_val : %p\n",getpid(),getppid(),g_val,&g_val);31 sleep(1);32 }33 }34 return 0;35 }
我们发现,但我们子进程修改全局变量g_val的时候,父进程的g_val没有受到影响,但是他们的地址都是一样的,这是为什么呢?
由此我们知道,这里的地址绝对不是物理内存的地址,而是虚拟地址(线性地址);并且几乎所有语言,如果有地址的概念,这个地址一定不是物理地址,而是虚拟地址。物理地址是由操作系统保管的。以下我们就开始介绍虚拟内存的作用
什么是地址空间
首先基本了解一下地址空间的排布情况
目前我们先不考虑解析这里的共享区
代码实现验证地址空间的排布
1 #include <stdio.h>2 #include <unistd.h>3 #include <stdlib.h>4 int g_val = 100;5 int g_unval;6 int main(int argc,char *argv[],char *env[])7 {8 //代码区9 printf("code addr:%p\n",main);10 //初始化数据11 printf("init global addr:%p\n",&g_val);12 //未初始化数据13 printf("uninit global addr:%p\n",&g_unval);14 //堆区15 char* heap_mem = (char*)malloc(10);16 char* heap_mem1 = (char*)malloc(10);17 char* heap_mem2 = (char*)malloc(10);18 char* heap_mem3 = (char*)malloc(10);19 printf("heap_mem addr:%p\n",heap_mem);20 printf("heap_mem1 addr:%p\n",heap_mem1);21 printf("heap_mem2 addr:%p\n",heap_mem2);22 printf("heap_mem3 addr:%p\n",heap_mem3);23 24 //栈区25 printf("stack addr:%p\n",&heap_mem);26 printf("stack addr:%p\n",&heap_mem1);27 printf("stack addr:%p\n",&heap_mem2);28 printf("stack addr:%p\n",&heap_mem3);29 //字面常量30 const char *str = "helloworld";31 printf("read only string addr: %p\n", str);32 33 int i,j;34 //命令区 35 for(i = 0 ;i < argc; i++) 36 { 37 printf("argv[%d]: %p\n", i, argv[i]);38 } 39 40 //环境区41 for(j = 0;env[j];++j)42 {43 printf("env[%d] addr:%p\n",j,&env[j]);44 }45 46 47 48 return 0;49 }
由此可见我们发现我们输入命令后,命令的地址在我们所执行的代码之后,这说明刚创建好这些变量就有了它自己本身的地址,地址程序结束后才打印,要分清前后
接下来我们来认识什么是地址空间
这时我们可以利用虚拟地址加映射机制(页表)来正确的讲地址存入物理内存
虚拟地址:不管哪个编译器,只要看到的地址都是虚拟地址,物理地址是操作系统保管的。
每一行代码都进行了编址。故,程序在编译的时候,每一个字段早已经具有了一个虚拟地址
=什么是映射机制?
映射机制可以将虚拟地址转换到物理地址,如果发现虚拟地址会越界或者错误,则就不会抛出,他起到了关键作用
那么映射机制是怎么判断的呢?
以上就是所描述的社么是地址空间,简单来说它是存储虚拟地址的。
地址空间和页表(用户级)是每一个进程都单独有一份的。
只要每一个进程的页表映射的是物理内存的不同区域,就可以做到进程之间不会互相干扰保证进程的独立性。
为什么要有地址空间
- 凡是非法的访问或者映射,os都会识别到,并终止你这个进程,有效的保护了物理内存。
因为地址空间和页表是os创建并维护的,所以凡是使用地址空间和页表的都会在os的监控下来进行范文,这样就间接的保护了物理内存中的所有合法数据和各个进程,以及内核的相关有效数据- 物理内存和进程的管理可以做到解耦合(没关联)。
当我们申请了物理空间,但是我们不立即使用的时候,就会造成内存空间的浪费;
针对这一现象,os做出了延迟分配的策略,来提高整机的效率。
因为地址空间的存在,所有申请的空间都是在地址空间上申请的,物理内存不是被申请到一个字节,当我们真正访问物理地址的时候,才执行内存相关的算法。帮助申请内存,构建页表之间的映射关系,这些都是由os自主完成的- 因为在物理内存中理论上随意加载,也是随意存放的,但是通过地址空间的虚拟地址和页表之间的映射,从进程视角来看所有的内存分布就成有序的了。
因为有地址空间的存在,每一个进程都认为自己单独有一块4GB(32)空间,并且各个区域是有序的。进而通过页表映射到不同区域,来实现进程的独立性,各个进程是不知道其他进程的存在的
回答问题,为什么地址相同值不同
发生了写时拷贝!,所以父子进程各自其实在物理内存中,有属于自己的变量空间!只不过在用户层用同一个变量(虚拟地址!)来标识了
相关文章:

【Linux】程序地址空间
程序地址空间 首先引入地址空间的作用什么是地址空间为什么要有地址空间 首先引入地址空间的作用 1 #include <stdio.h>2 #include <unistd.h>3 #include <stdlib.h>4 int g_val 100;6 int main()7 {8 pid_t id fork();9 if(id 0)10 {11 int cn…...

springboot 设置自定义启动banner背景图 教程
springboot banner Spring Boot中的banner是在应用程序启动时显示的一个ASCII艺术字符或文本。它被用来给用户展示一些关于应用程序的信息,例如名称、版本号或者公司标志等。 使用Spring Boot的默认设置,如果项目中有一个名为“banner.txt”的文件放置…...

CSS的引入方式有哪些?
聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 内联样式(Inline Styles)⭐ 内部样式表(Internal Stylesheet)⭐ 外部样式表(External Stylesheet)⭐ 导入样式表(Import Stylesheet)⭐ 写在最…...

.net core的Knife4jUI,让swagger更精致
要在 .NET Core 中使用 IGeekFan.AspNetCore.Knife4jUI,您可以按照以下步骤进行配置: 首先,安装 IGeekFan.AspNetCore.Knife4jUI NuGet 包。可以通过 Visual Studio 的 NuGet 包管理器或者 .NET CLI 进行安装。 在 Startup.cs 文件的 Config…...
Android 开发中需要了解的 Gradle 知识
作者:wkxjc Gradle 是一个基于 Groovy 的构建工具,用于构建 Android 应用程序。在 Android 开发中,了解 Gradle 是非常重要的,因为它是 Android Studio 默认的构建工具,可以帮助我们管理依赖项、构建应用程序、运行测试…...

Linux之【进程间通信(IPC)】-总结篇
Linux之【进程间通信(IPC)】-总结篇 管道System V共享内存System V消息队列System V信号量IPC资源的管理方式 往期文章 1.进程间通信之管道 2.进程间通信之System V共享内存 管道 进程之间具有独立性,拥有自己的虚拟地址空间,因…...

C++QT教程3——手册4.11.1自带教程(笔记)——创建一个基于Qt Widget的应用程序
文章目录 创建一个基于Qt Widget的应用程序创建Text Finder项目素材文件 填补缺失的部分设计用户界面完成头文件完成源文件创建资源文件 编译和运行程序 参考文章 创建一个基于Qt Widget的应用程序 本教程介绍如何使用Qt Creator创建一个小型Qt应用程序,名为Text F…...

手机商城网站的分析与设计(论文+源码)_kaic
目录 摘 要 1 1 绪论 2 1.1选题背景意义 2 1.2国内外研究现状 2 1.2.1国内研究现状 2 1.2.2国外研究现状 3 1.3研究内容 3 2 网上手机商城网站相关技术 4 2.1.NET框架 4 2.2Access数据库 4 2.3 JavaScript技术 4 3网上手机商城网站分析与设…...

vue2 封装 webSocket 开箱即用
第一步: 下载 webSocket npm install vue-native-websocket --save 第二步: 需要在 main.js 中 引入 import websocket from vue-native-websocket; Vue.use(websocket, , {connectManually: true, // 手动连接format: json, // json格式reconnection:…...

使用fopen等标准C库来操作文件
fopen 需要的头文件: #include <stdio.h> 函数原型: FILE *fopen(const char *pathname, const char *mode); 参数: pathname: 文件路径mode: “r” :以只读方式打开文件,该文件必须存在。“w” ÿ…...
Spring-Cloud-Loadblancer详细分析_1
背景 从SpringCloud 2020 版本之后,组件移除了除 Eureka 以外,所有 Netflix 的相关,包括最常用的 Ribbon Hystrix 等,所以 SpringCloud 在 spring-cloud-commons 提供了Loadbalancer 用来替代 Ribbon。本系列就来介绍Loadbalance…...
键盘键码keyCode对照表
字母和数字键的键码值(KeyCode)按键键码按键键码A65J74B66K75C67L76D68M77E69N78F70O79G71P80H72Q81I73R82 字母和数字键的键码值(KeyCode)按键键码按键键码S83149T84250U85351V86452W87553X88654Y89755Z90856048957 数字键盘上的键的键码值(KeyCode)按键键码按键键码0968104…...

jupyter切换conda虚拟环境
环境安装 conda install nb_conda 进入你想使用的虚拟环境: conda activate your_env_name 在你想使用的conda虚拟环境中: conda install -y jupyter 在虚拟环境中安装jupyter: conda install -y jupyter 重启jupyter 此时我们已经把该安装…...
【数据结构•堆】经典问题:k路归并
题目描述 k路归并问题: 把k个有序表合并成一个有序表。( k < 10^4 ) 输入输出格式 输入格式: 输入数据共有 2*k1 行。 第一行,一个整数k( k < 10^4 ),表示有k个有序…...
VUE3 动态路由
带参数的动态路由匹配 很多时候,我们需要将给定匹配模式的路由映射到同一个组件。例如,我们可能有一个 User 组件,它应该对所有用户进行渲染,但用户 ID 不同。在 Vue Router 中,我们可以在路径中使用一个动态字段来实现…...

CentOS软件包管理rpm、yum
一、软件包概述 Linux常见软件包分为两种,分别是源代码包、二进制文件包。源代码包是没有经过编译的包,需要经过GCC、C编译器编译才能运行,文件内容包含源代码文件,通常以.tar.gz、.zip、.rar结尾;二进制包无需编译&am…...

【VSCode】报错:出现段错误解决办法 (Segmentation fault)
VScode报错:Segmentation fault (core dumped)的解决办法 解决Program received signal SIGSEGV, Segmentation fault.的辛酸 Linux环境下段错误的产生原因及调试方法小结 Linux下的段错误Segmentationfault产生的原因及调试方法经典.pdf 在程序中,TF…...
Linux Centos 8 用户管理之重置密码
如果在使用linux系统时遇到系统密码问题无法进入系统或者操作的时候可以按照下面的方法重置用户密码。 一、root用户密码重置: 方式一: 1.重启电脑或虚拟机,在刚进引导界面时候按“e"键,进入编辑模式。 2.在”quiet"…...

C语言快速回顾(三)
前言 在Android音视频开发中,网上知识点过于零碎,自学起来难度非常大,不过音视频大牛Jhuster提出了《Android 音视频从入门到提高 - 任务列表》,结合我自己的工作学习经历,我准备写一个音视频系列blog。C/C是音视频必…...

【Apollo】Apollo-ros版本架构学习与源码分析
😏★,:.☆( ̄▽ ̄)/$:.★ 😏 这篇文章主要介绍Apollo-ros版本架构学习与源码分析。 无专精则不能成,无涉猎则不能通。——梁启超 欢迎来到我的博客,一起学习,共同进步。 喜欢的朋友可以关注一下&a…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...

linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...

华为OD机考-机房布局
import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...
C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...

【Linux系统】Linux环境变量:系统配置的隐形指挥官
。# Linux系列 文章目录 前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变量的生命周期 四、环境变量的组织方式五、C语言对环境变量的操作5.1 设置环境变量:setenv5.2 删除环境变量:unsetenv5.3 遍历所有环境…...