【Linux进行时】进程地址空间

进程地址空间

在这里插入图片描述

例子引入:

我们在讲C语言的时候,老师给大家画过这样的空间布局图,但是我们对它不了解

image-20231001211243614

我们写一个代码来验证Linux进程地址空间

#include<stdio.h>
#include<assert.h>
#include<unistd.h>
int g_value=100;
int main()
{pid_t id=fork();assert(id>=0);if(id==0){//childwhile(1){printf("我是子进程,我的id是:%d,我的父进程是:%d,  g_value:%d,&g_value:%p\n",getpid(),getppid(),g_value,&g_value);sleep(1);}}                                                                                                                             else{//fatherwhile(1){printf("我是父进程,我的id是:%d,我的父进程是:%d,g_value:%d,&g_value:%p\n",getpid(),getppid(),g_value,&g_value);sleep(2);}          }  return 0;
}          

image-20230819095438860

这里没什么问题,就是他们的g_valule 和其地址都是一样的,

我们将代码调整一下,让子进程的g_value++

#include<stdio.h>
#include<assert.h>
#include<unistd.h>
int g_value=100;
int main()
{pid_t id=fork();assert(id>=0);if(id==0){//childwhile(1){printf("我是子进程,我的id是:%d,我的父进程是:%d,g_value:%d,&g_value:%p\n",getpid(),getppid(),g_value,&g_value);sleep(1);g_value++;//只有子进程会进行修改}}                                                                                                                             else{//fatherwhile(1){printf("我是父进程,我的id是:%d,我的父进程是:%d,g_value:%d,&g_value:%p\n",getpid(),getppid(),g_value,&g_value);sleep(2);}          }  return 0;
}                                 

image-20230819095954894

我们可以发现子进程的g_value变了,但是父进程没有变,两个的地址还是一样的

❓为什么他们两个地址相同但是读出来的数据不同呢?(下文会解答)

🔥子进程对全局数据修改,并不影响父进程!——进程具有独立性!

❓这个地址会是物理地址?💡不会

显然这个地址绝对不是物理地址!所以我们平常在语言层面用的地址,绝对不是物理地址,所以以前用的指针绝对不是地址,其实这个地址叫做虚拟地址or线性地址

故事引入:

香港某个老板非常滴有钱,有10亿美金,他有 4个私生子,每个私生子都并不知道对方的存在,他们都以为自己是独生子。因为他们彼此不知道对方的存在,所以他们在生活和工作上也没有交集,不会有任何互相的影响(这就是独立性的体现)。财阀老板为了维护自己的独立性:

他就对大儿子说:“儿子,你好好学习,以后老爹钱都是你的。”,大儿子一听卧槽真好,高枕无忧,就好好学习,一想到自己以后有钱,就更想学习了。

然后又对二儿子说:“儿子,好好工作,等以后我就把公司给你。”,二儿子一听热泪盈眶,于是就好好工作,等着将来有一天可以继承公司。

后来又对三儿子说:“儿子,你好好干活,等你长大老爹的家产交给你!”,三儿子知道自己以后会继承老爹的所有财产,开心坏了,就努力的干活。

后来又对四儿子说:“儿子,你好好干活,等你长大老爹的家产交给你!”,四儿子知道自己以后会继承老爹的所有财产,开心坏了,就努力的干活。

只要在财阀爹的可承受范围内,孩子要多少钱他都给多少钱,所以三个儿子自然都认为自己有很多钱。财阀老板给他的三个儿子画了一张虚拟的、不存在的大饼,让他们都能努力学习工作干活(这个步骤就是给他们分别建立了进程地址空间)。

image-20230819102740749

画的饼:进程地址空间,10亿美金:内存,老板:操作系统,四个私生子是进程

❓大富翁,要不要把“饼”管理起来呢?

显然需要的,遵循先描述再组织的原则

所以,进程地址空间,就是就是给进程画的大饼

进程地址空间 → 逻辑上抽象的概念 → 让每个进程都认为自己独占系统的所有资源

**概念:**操作系统通过软件的方式,给进程提供一个软件视角,认为自己是独占系统的所有资源(内存)。

image-20231001212605706

区域和页表:

什么叫做区域?我们来拿一张桌子来理解,初中的时候小花和小胖分过 “38线”

三八线的本质就是区域划分!

image-20230819105220732

🔥地址空间本身就是一个线性区域,地址空间是线性结构的!

struct mm_struct {long code_start;long code_end;long init_start;long init_end;long uninit_start;long uninit_end;long heap_start;long heap_end;long stack_start;long stack_end;...
}

如果限定了区域,那么区域之间的数据是什么?

是虚拟地址or线性地址

🔥程序加载到内存,由程序变成进程后,由操作系统给每个进程构建的一个页表结构,就是 页表

🔥数据和代码真正只能在内存中!

找到地址不是目的,而是手段

image-20230820093416558

回到之前那个问题:

❓为什么他们两个地址相同但是读出来的数据不同呢?

💡如果子进程对数据进行了修改,因为进程具有独立性,子进程的修改不能影响父进程

子进程这里的 物理地址改了,但是虚拟地址没有改

写时拷贝发生在物理地址,虚拟地址没有变

因为进程具有独立性,比如如果此时子进程把变量改了(写入),就会导致父进程识别的问题就出现了父进程和子进程不一的情况,因为进程是具有独立性的,所以我们就要做到互不影响。我们的子进程要进行修改了,影响到父进程怎么办?没关系!操作系统会出手!当我们识别到子进程要修改时,操作系统会重新给子进程开辟一段空间,并且把 100 拷贝下来,重新给进程建立映射关系,所以子进程的页表就不再指向父进程所对应的 100 了,而直接指向新的 100。你在做修改时又把它的值从 100 改成 200 时,我们就出现了 “改的时候永远改的是页表的右侧,左侧不变” 的情况,所以最后你看到了父子进程的虚拟地址一样,但是经过页表映射到了不同的物理内存,所以了你看到了一个是 100 一个是 200,父子进程的数据不同的结果。

我们的操作系统当我们的父子对数据进行修改时,操作系统会给修改的一方重新开辟一块空间,并且把原始数据拷贝到新空间当中,这种行为就是 写时拷贝!

当父子有任何一个进程尝试修改对应变量时,有一个人想修改,就会触发写时拷贝,让他去拷贝新的物理内存,这只需要重新构建也表的映射关系,虚拟地址是不发生任何变化的,所以最终你看的结果是虚拟地址不变,而内容不同。

这个结构也体现了进程具有独立性

pid_t id=fork()
if(){}
else
{}

❓fork在返回的时候,父子都有,return两次,id是不是pid_T类型定义的变量呢?

💡是的,返回的本质就是写入!谁先返回,谁就让OS发生写时拷贝

如果是父进程就返回pid,如果是子进程就返回0

为什么进程地址空间要存在?

❓如果没有地址空间,我们OS是如何工作呢?

💡这里就是害怕野指针的情况,要寻找一个地址因为你的代码错误找到了一个越界地址时写入时会使别人的进程错了而且很不安全,因此有了页表和虚拟空间

🔥这两个存在的意义:1.防止地址随意访问,保护物理内存与其他进程

❓常量字符串不能修改,这是为什么呢?💡因为页表访问的时候是有权限的,权限不能修改

char*str=“hello world”;
*str=‘H’;

🔥先来将另外一个扩充:malloc的本质——

❓向OS申请内存,操作系统立马给你,还是说在你需要的时候给你?

💡1.在你需要的时候给你,OS一般不允许任何的浪费或者不高效

2.申请内存==立马使用呢?不一定等于立马使用

3.在你申请成功之后,和你使用之前就有一段小小的时间窗口,这个空间没有被正常使用,但是别人用不了—-闲置状态

🔥如果有500进程这样的话,这样操作系统就有大块的空间处于这种状态,这种情况叫做缺页中断

❓因为有页表,你关心不关心你申请的空间是在物理空间的哪一块呢?💡不关心,一样的

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

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

相关文章

Chrome之解决DevTools: Failed to load data:No resource with given identifier found

问题 使用DevTools抓包时候, 有些跨域请求无法在加载出来, 提示 Failed to load data:No resource with given identifier found 解决办法 换其他浏览器 下断点 打开DevTools, 选择源代码/来源/Sources,找到事件监听器断点/Event Listener Breakpoints, 找到加载/Load下面…

<学习笔记>从零开始自学Python-之-常用库篇(十二)Matplotlib

Matplotlib 是Python中类似 MATLAB的绘图工具&#xff0c;Matplotlib是Python中最常用的可视化工具之一&#xff0c;可以非常方便地创建2D图表和一些基本的3D图表&#xff0c;可根据数据集&#xff08;DataFrame&#xff0c;Series&#xff09;自行定义x,y轴&#xff0c;绘制图…

云可观测性安全平台——掌动智能

云可观测性安全平台是一个跨架构、跨平台的可观测性方案&#xff0c;实现对云环境下的细粒度数据可视化&#xff0c;满足安全部门对云内部安全领域的多场景诉求&#xff0c;包括敏感数据动态监管、云网攻击回溯分析、攻击横移风险监控、云异常流量分析。本文将介绍掌动智能云可…

【ldt_struct】0ctf2021-kernote

前言 题目给的文件系统是 ext4&#xff0c;所以我们只需要将其挂载即可使用&#xff1a; 1、创建一个空目录 2、使用 mount 将其挂载即可 3、使用 umount 卸载即可完成打包 开启了 smap、smep、kaslr 和 kpti 保护&#xff0c;并且给了如下内核编译选项&#xff1a; Her…

java web+Mysql e-life智能生活小区物业管理系统

本项目为本人自己书写&#xff0c;主要服务小区业主和管理人员。 e-life智能生活小区涉及多个方面的智能化和便利化服务&#xff1a; 1. 用户模块&#xff1a;包含基本的登入登出操作&#xff0c;查看个人信息中用户可以查看 自己的个人资料但不可以修改个人信息。 a) 用户…

聊聊分布式架构——序列化和反序列化

目录 序列化与反序列化 为什么需要序列化 常见的序列化方式 java的序列化示例 transient排除序列化 Java序列化的简单总结 序列化与反序列化 序列化就是把对象的状态信息转化为可存储或传输的形式过程&#xff0c;也就是把对象转化为字节序列的过程称为对象的序列化。 反…

Docker快速搭建漏洞靶场指南

user: admin passwrod&#xff1a;password 查看容器是否已开启&#xff1a; 最常见漏洞&#xff1a; 防护级别提高后&#xff1a; 更改防护级别&#xff1a; 复现vulhub漏洞靶场&#xff1a; 开启&#xff1a; 一个是漏洞类型一个是真实的漏洞靶场。

去雨去雪去雾算法之本地与服务器的TensorBoard使用教程

在进行去雨去雾去雪算法实验时&#xff0c;需要注意几个参数设置&#xff0c;num_workers只能设置为0&#xff0c;否则会报各种稀奇古怪的错误。 本地使用TensorBoard 此外&#xff0c;发现生成的文件是events.out.tfevents格式的&#xff0c;查询了一番得知该文件是通过Tens…

asp.net core mvc 文件上传,下载,预览

//文件上传用到了IformFile接口 1.1文件上传视图 <form action"/stu/upload" method"post" enctype"multipart/form-data"><input type"file" name"img" /><input type"submit" value"上传&…

Lwip的接收邮箱大小的影响

LwIP&#xff08;Lightweight IP&#xff09;是一个用于嵌入式系统的轻量级的TCP/IP协议栈&#xff0c;它支持UDP和其他网络协议。 接收邮箱大小 在LwIP中&#xff0c;UDP接收邮箱的大小对系统性能和可靠性有一定影响。 首先&#xff0c;UDP接收邮箱的大小决定了可以同时接收…

联想Lenovo 威6 15-ITL(82F2)原厂Win10系统

lenovo联想原装出厂系统 自带所有驱动、出厂主题壁纸LOGO、Office办公软件、联想电脑管家等预装程序 下载链接&#xff1a;https://pan.baidu.com/s/1darORHmIyAXkD7HvKRNHNw?pwddh6e 所需要工具&#xff1a;16G或以上的U盘 文件格式&#xff1a;ISO 文件大小&#xff1a;11.…

(三)激光线扫描-中心线提取

光条纹中心提取算法是决定线结构光三维重建精度以及光条纹轮廓定位准确性的重要因素。 1. 光条的高斯分布 激光线条和打手电筒一样,中间最亮,越像周围延申,光强越弱,这个规则符合高斯分布,如下图。 2. 传统光条纹中心提取算法 传统的光条纹中心提取算法有 灰度重心法、…