Linux学习记录——십삼 程序地址空间

news2024/11/20 20:39:51

文章目录

  • 1、了解程序地址测试代码
  • 2、理解程序地址空间
  • 3、程序地址空间存在的意义


1、了解程序地址测试代码

  1 #include <stdio.h>
  2 #include <assert.h>
  3 #include <unistd.h>
  4 
  5 int g_value = 100;
  6 int main()
  7 {
  8     pid_t id = fork();
  9     assert(id >= 0);
 10     if(id == 0)
 11     {
 12         //child
 13         while(1)
 14         {
 15           printf("我是子进程, 我的id是: %d, 我的父进程是: %d, g_value: %d, &g_value: %p\n", \
 16               getpid(), getppid(), g_value, &g_value);
 17           sleep(1);                                                                                                                                                                                                            
 18         }
 19     }                    
 20     else
 21     {   
 22         //father
 23         while(1)
 24         {       
 25          
 26           printf("我是父进程, 我的id是: %d, 我的父进程是: %d, g_value: %d, &g_value: %p\n", \
 27               getpid(), getppid(), g_value, &g_value);                                        
 28           sleep(2);                                   
 29         }          
 30     }    
 31 }   

在这里插入图片描述

如果在子进程循环里写上g_value++,虽然它是全局变量,但对父进程没有影响。

在这里插入图片描述

这就是进程具有独立性。之前写过进程 = 内核数据结构 + 代码和数据,两个各自也都有独立性,保证相互独立的做法就是写时拷贝。

再看最后的地址。全都一样。g_value经过写时拷贝会变成两个变量,打印出来的地址应当是不一样的。如果是物理地址,读取同一个变量的地址,那么不会出现不同。子进程对变量进行了修改,但是父进程没有读取到,所以这个地址并不是物理地址。那么现在用的这个地址叫虚拟地址或者线性地址。

2、理解程序地址空间

操作系统会给进程分配好该有的内存量,比如有10g内存,3个进程,分别给他们仨3 3 4g内存。系统要管理进程地址空间,空间本质是一个内核数据结构,struct mm_struct{}。进程在申请空间时,不会之间把所有分配给的空间全要上,只要够这次程序用的空间,如果要得太多,系统也会拒绝。

地址空间会被分成很多区,比如栈区堆区等。所以存入地址空间的数据最终都会进入物理内存中。程序在访问数据时会访问地址空间,用的就是虚拟地址。

==程序地址空间的各个区域如何理解?==区域的划分就是对线性区域进行指定start和end即可完成区域划分。程序地址空间是一个线性区域,从低地址到高地址分布,32位下每个地址是1个字节。这和真实内存一样,32位机器下,CPU访问内存中某个地址或者数据时,会先编址,编成只有0和1,而CPU与内存之间有2的32次方种连接,也就是2的32次方个地址,差不多4G,CPU就需要在这里面寻址,CPU寻址的最小大内单位是1字节。程序地址空间也是如此,地址是连续的,每个都保证了唯一性,所以是线性区域,每个地址所能存储的最大空间是1字节。程序地址空间的地址是从0x全0到0x全F。

一个整数存进去时,占连续的4个字节,而整数的地址就是4个字节中最低的那个地址,数据类型则确定了从这个地址往后读几位。

程序地址空间是一个线性空间,系统对它的大小是早就计算好的,32位和64位的源代码不一样,32位的结构体就直接是4G。空间中每个区域会这样定义:

long code_start
long code_end
long init_start
long init_end

每个区域对应各自的变量名。

如果限定了区域,区域之间的数据就是虚拟地址或者线性地址。

区域的扩大缩小就是修改边界值start和end。

虽然有程序地址空间,但实际上数据只能存在内存中。虚拟地址在系统中会通过页表转为物理地址。

-------------------------------------------------------------

回到刚才的问题,子进程修改数值不影响父进程。父进程和子进程都有各自的地址空间,通过页表连接到物理空间,当子进程想修改数据,内存会给他再申请另一块空间,数据也拷贝过去,子进程就连接到这个新的空间,所以他们的虚拟地址一样,但是连接到物理空间后数值不一样,因为在物理空间中访问的空间不一样。

-------------------------------------------------------------

代码中还有一个问题,为什么if和else都能运行?这是因为fork在返回的时候,父子进程都有了,所以会return两次,id是pid_t类型定义的局部变量,而return的本质,就是在写入,所以谁先返回,谁就会让操作系统发生写时拷贝。

3、程序地址空间存在的意义

如果只有物理内存,那么一个个程序在写入数据时,如果存在越界,或者野指针,那么其他区域的数据就可能被改变了,所以引入地址空间和页表,通过地址空间和页表向物理空间的映射,系统检测映射成功后就可以找到地址和数据。

malloc的本质

malloc申请的时候,返回的也是物理空间上一个堆区的地址,也要通过地址空间和页表。申请并不一定会马上就给空间,而是系统认为你需要才会给你,系统一定要以高效为主。malloc申请空间时,系统开辟空间后,会先进入闲置状态,这时候别人无法用,并且页表也不会去映射,物理内存也没有开辟空间,页表倒是会有虚拟地址。当用户开始写入时,系统就会重新做一遍,把映射加上,物理上开辟空间,用户才能正常用,这就是缺页中断。

地址空间的调整,和页表的连接属于进程管理,页表和物理空间的映射,物理空间的管理属于内存管理。

重新理解地址空间

源代码被编译的时候,会按照虚拟地址空间的方式对代码和数据进行编制,地址空间不仅会影响系统,也会让编译器遵守它的规则。

Linux中可执行程序的格式一般是ELF格式。

读取程序的时候,数据中包含的地址都是虚拟地址,用来更便利地找到相应的物理地址。程序中的地址是虚拟地址,内存中是物理地址。

地址空间和页表存在的意义:
1、防止地址随意访问,保护物理内存与其他进程
2、进程管理和内存管理进行解耦合
3、可以让进程以统一的视角看待自己的代码和数据

结束。

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

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

相关文章

设计模式之结构型模式

1、代理模式1.1 静态代理1.2 jdk 动态代理1.3 CGLIB 动态代理1.4 优缺点2、适配器模式2.1 类适配器模式2.2 对象适配器模式2.3 JDK 源码解析3、装饰者模式3.1 JDK 源码解析3.2 代理模式与装饰者模式的区别4、桥接模式5、外观模式6、组合模式6.1 组合模式的分类6.2 优点及使用场…

ZincSearch Java 客户端教程

ZincSearch Zinc 简单、强大&#xff0c;不了解的同学可以参见我之前的博客。今天我们这里谈谈 Java 环境如何集成 Zinc 客户端&#xff0c;跟如何使用的。 安装 Zinc 到 Github 的官方 Releases 下载&#xff1a; 我的是 Windows 开发环境&#xff0c;下载 zincsearch_0.4…

基于支持向量机SVM的面部表情分类预测

目录 支持向量机SVM的详细原理 SVM的定义 SVM理论 Libsvm工具箱详解 简介 参数说明 易错及常见问题 SVM应用实例,基于SVM的面部表情分类预测 代码 结果分析 展望 支持向量机SVM的详细原理 SVM的定义 支持向量机(support vector machines, SVM)是一种二分类模型,它的基本…

【网络】-- 网络编程套接字(铺垫、预备)

目录 理解源IP地址和目的IP地址 认识端口号 端口号 理解源端口号和目的端口号 套接字 认识TCP与UDP协议 网络字节序 socket编程接口 socket 常见API sockaddr结构 理解源IP地址和目的IP地址 就如同我们唐僧的取经路&#xff1a; 唐僧的出发地到目的地&#xff1a;东…

阿尔法开发板 .bin 文件烧写

一. IMX6ULL 开发板简介 IMX6ULL 开发板是正点原子提供的阿尔法开发板&#xff0c;所用芯片为恩智浦&#xff0c;基于 Cortex-A7 架构。 这里介绍一下裸机篇中&#xff0c;关于如何将 .bin 文件烧写进 SD 卡&#xff0c;从而设备运行程序。 二. xx.bin 文件烧写 IMX6ULL支…

句子的改写和扩写

目录 1.句子改写 2.句子扩写 &#xff08;不低于15个句子算是长句子&#xff0c;不能太多长句子&#xff09; 1.句子改写 我绝不会嫁给你的。 如果你是世界上最后一个男人&#xff0c;我就去寺庙。 If you married me,I would jump into the well. 如果你嫁给我&#xff0c;我…

【Java学习笔记】5.Java 基本数据类型

Java 基本数据类型 变量就是申请内存来存储值。也就是说&#xff0c;当创建变量的时候&#xff0c;需要在内存中申请空间。 内存管理系统根据变量的类型为变量分配存储空间&#xff0c;分配的空间只能用来储存该类型数据。 因此&#xff0c;通过定义不同类型的变量&#xf…

计算机网络的166个概念你知道几个 第三部分

广播&#xff1a;我们一般小时候经常会广播体操&#xff0c;这就是广播的一个事例&#xff0c;主机和与他连接的所有端系统相连&#xff0c;主机将信号发送给所有的端系统。 多播&#xff1a;多播与广播很类似&#xff0c;也是将消息发送给多个接收主机&#xff0c;不同之处在于…

最近一年我都干了什么——反思!!

过去一年不管是学习方式还是心态上都和以往有了许多不同的地方&#xff0c;比较昏昏沉沉。最近慢慢找到状态了&#xff0c;就想赶紧记录下来。 学习 在学习新技术的过程中开始飘了&#xff0c;总感觉有了一些开发经验后就觉得什么都不用记&#xff0c;知道思路就行遇到了现场百…

15、正则表达式

目录 一、元字符 二、限定修饰符 一、元字符 正则表达式通常被用于判断语句中&#xff0c;用来检查某一字符串是否满足某一格式。正则表达式是含有一些具有特殊意义字符的字符串&#xff0c;这些特殊字符称为正则表达式的元字符。例如&#xff0c;“\\d”表示数字0~9中的任何…

BUU [ZJCTF 2019]Login

这是一道让我感觉很淦的题&#xff0c;整一天了才大致了解了来龙去脉 开始&#xff1a; 首先丢到虚拟机checksec一下看看有啥保护措施&#xff1a; 看到开了Canary&#xff0c;就已经感觉不妙了&#xff0c;接着丢到IDA里看看啥情况 一看&#xff0c;是令人痛苦的c风格的代码…

IDEA中使用Tomcat的两种方式:集成本地Tomcat使用Tomcat Maven插件

一、前言 在IDEA中创建完一个Maven Web项目&#xff0c;并补齐了目录以后&#xff0c;准备使用Tomcat时&#xff0c;就需要在自己创建的项目中去部署Tomcat&#xff0c;前文已经介绍了如何创建Maven Web&#xff0c;所以这里就不多加赘述&#xff0c;直接讲述部署Tomcat的方法…

fastadmin后台登录页修改

直接替换就行 <!DOCTYPE html> <html lang"{$config.language}"> <head>{include file"common/meta" /}<style type"text/css">body {color: #999;background-color: #f1f4fd;background-size: cover;}a {color: #444;…

[极客大挑战 2019]EasySQL 1

[极客大挑战 2019]EasySQL 1解题POC一、解题思路之暴力破解1. 弱口令2. 暴力破解二、解题思路之万能密码1. 什么是万能密码2. 测试过程解题POC 直接点击登录获取flagflag{62f0d2ca-579e-450e-941f-5f7c23a8baf7} 一、解题思路之暴力破解 这题是万能密码&#xff0c;所以暴力破解…

推荐一个.Net Core开发的Websocket群聊、私聊的开源项目

更多开源项目请查看&#xff1a;一个专注推荐.Net开源项目的榜单 今天给大家推荐一个使用Websocket协议实现的、高性能即时聊天组件&#xff0c;可用于群聊、好友聊天、游戏直播等场景。 项目简介 这是一个基于.Net Core开发的、简单、高性能的通讯组件&#xff0c;支持点对点…

面试题---CSS

面试题---CSS子绝父相下&#xff0c;子百分比的问题两栏布局问题三栏布局问题---圣杯问题(三栏&#xff0c;左右固定&#xff0c;中间自适应)。内联样式与块级样式的区别怎么让一个 div 水平垂直居中分析比较 display: none 、visibility: hidden、opacity: 0优劣和适用场景css…

Day5: platformDriver-1

Platform Driver (1) Linux kernel中大部分设备可以归结为平台设备&#xff0c;因此大部分的驱动是平台驱动&#xff08;patform driver&#xff09; 什么是平台设备 平台设备是linux的设备模型中一类设备的抽象。 内核中的描述&#xff1a; Platform devices are devices t…

CUDA By Example笔记--Julia集合的并行计算

目录 1--linux报错汇总 1-1 使用 nvcc 命令编译报错 1-2--使用 CMake 编译源码报错 2--源码解读 1--linux报错汇总 1-1 使用 nvcc 命令编译报错 使用 nvcc ./julia_gpu.cu -lglut -lGLU -lGL 运行时&#xff0c;显示 cannot find -lglut 的错误&#xff0c;定位 "gl_…

linux配置核查MySQL 配置规范 (Linux)_S3A3G3

linux的配置核查问题&#xff1a; 解决&#xff1a; 1.检查是否禁止mysql对本地文件存取 方法一&#xff1a;在my.cnf的mysql字段下加local-infile0 方法二&#xff1a;启动mysql时加参数local-infile0 /etc/init.d/mysql start --local-infile0 假如需要获取本地文件&#xf…

【C语言——练习题】指针,你真的学会了吗?

✨✨✨✨如果文章对你有帮助记得点赞收藏关注哦&#xff01;&#xff01;✨✨✨✨ 文章目录✨✨✨✨如果文章对你有帮助记得点赞收藏关注哦&#xff01;&#xff01;✨✨✨✨一维数组练习题&#xff1a;字符数组练习题&#xff1a;字符指针练习题&#xff1a;二维数组练习题&am…