【Linux】进程地址空间

news2024/9/21 14:48:15

文章目录

  • 一、前言
  • 二、什么是进程地址空间
  • 三、进程地址空间如何进行管理
  • 四、为什么会存在进程地址空间
  • 五、进程地址空间区域的严格划分

一、前言

学习Linux系统编程一共要翻越三座大山 – 进程地址空间、文件系统以及多线程,这三部分内容很难但是非常重要;而今天我们将要征服的就是其中的第一座高山 – 进程地址空间。

二、什么是进程地址空间

我们以前在学习 C/C++ 的动态内存管理的时候,通常把地址空间划分为如下几个区域:image-20221117140002036

但是我们上面的地址空间是真正的物理空间吗?我们以一个例子来测试:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int g_val = 100;

int main()
{
    int id = fork();
    if(id < 0)
    {
        perror("fork fail");
        return 1;
    }
    else if(id == 0)
    {
        int cnt = 0;
        while(1)
        {
            if(cnt == 5)
            {
                g_val = 200;
                printf("子进程已经修改了全局变量...........................\n");
            }
            cnt++;
            printf("我是子进程,pid:%d, ppid:%d, g_val:%d, &g_val:%p\n", getpid(), getppid(), g_val, &g_val);
            sleep(1);
        }
    }
    else 
    {
        while(1)
        {
            printf("我是父进程,pid:%d, ppid:%d, g_val:%d, &g_val:%p\n", getpid(), getppid(), g_val, &g_val);
            sleep(1);
        }
    }
    return 0;
}

image-20221117141746706

我们可以看到,当子进程修改了全局变量 g_val 的值以后,子进程和父进程的 g_val 不同,这是正常的,因为我们在上一节进程概念中就说过,进程具有独立性,不同进程之间互不影响,包括父子进程;但是这里还发生了一个神奇的现象 – 子进程和父进程 g_val 的地址竟然是一样的!

这说明了我们上面得到的 g_val 的地址不是真实的地址 (物理地址) – 因为在同一时间内一个物理地址中只能存储一个进程的数据,不同进程的不同数据不可能同时存在于同一个物理内存中,所以出现上面这种状况的原因只能是我们得到的地址不是物理地址。

实际上操作系统会给每一个进程都创建一个独立的虚拟地址空间,然后通过页表将虚拟地址空间与物理内存一一对应 (映射),我们用户只能得到虚拟地址空间中的虚拟地址,当我们修改虚拟地址中的数据时,操作系统会先通过页表找到对应的物理内存,然后修改物理内存中的数据。

此时,我们就能解释上面的现象了 – 子进程和父进程都拥有自己的单独的进程地址空间,且子进程的地址空间是从父进程那里拷贝来的,所以最开始二者的 g_val 其实指向同一块物理内存;

现在子进程想要修改自己地址空间中 g_val 的值,当操作系统通过页表找到 g_val 的物理内存时,发现 g_val 是被两个进程共同指向的,为了保证进程的独立性,OS 会在物理内存中寻找一块新空间,然后将原空间的数据拷贝到新空间,再修改子进程的页表映射关系,最后再修改新空间中 g_val 的值,上述过程叫做 写时拷贝

所以虽然子进程和父进程 g_val 的虚拟地址相同,但是它们通过各自的页表映射到的物理地址是不相同的,自然也可以从物理内存中取出不同的数据。

image-20221117200649443

注:在操作系统中,进程地址空间中的地址通常也被称为线性地址,因为它是按比特位从全0到全1依次顺序编址的;磁盘程序内部的地址通常被称为逻辑地址;在其他地方,线性地址、虚拟地址、逻辑地址区分比较严格,但是在Linux中,三者的意思是一样的,都表示虚拟地址,大家不用过于区分。

Tips:OS 为每个进程都创建独立的地址空间就相当于给每个进程都画了一个"大饼",即告诉每个进程:“你享有计算机中的所有资源,整个系统内存都是你的,你快来用吧!” 而实际上,一旦某个进程申请的内存过大时,OS 会直接拒绝进程的请求。


三、进程地址空间如何进行管理

OS 如何管理进程地址空间

OS 会为系统中的每一个进程都创建一个进程地址空间,但是 OS 内部同时存在着许多进程,所以为了保证各个进程正常运行,OS 需要对每个进程的地址空间进行管理。

那么 OS 如何对进程地址空间进行管理呢?在学习了 【Linux】计算机的软硬件体系结构 后,对于这个问题,相信大家已经能够轻松拿捏了 – 管理的本质是对数据进行管理,管理的方法是先描述,再组织。

所以和管理进程一样,操作系统会使用一种内核数据结构来对地址空间进行管理,Linux中用于 管理地址空间的内核数据结构叫做 mm_struct,操作系统会为每个进程创建一个 mm_struct 对象,然后通过管理结构体对象来间接管理进程地址空间。

Linux 中 mm_struct 源码如下:image-20221117151606475

image-20221117151711447

可以看到,进程地址空间其实也是进程属性的一种,我们可以通过进程的 task_struct 来找到/管理进程对应的地址空间。

进程地址空间如何进行区域划分以及区域调整

我们知道进程地址空间被划分为很多个区域,其中我们熟知的有堆区、栈区、已初始化全局数据区、未初始化全局数据区、代码段,那么操作系统如何对这些区域进行划分和管理呢?答案是用通过两个表示区域边界的变量 start、end 来维护一块内存区域,比如:

struct mm_struct {
    //uint32_t:32位系统下的无符号整型
	uint32_t code_start, code_end;
    uint32_t date_start, code_end;
    uint32_t heap_start, heap_end;
    unit32_t stack_start, stack_end;
    ...
};

Linux mm_struct 中关于区域划分的部分源码如下:image-20221117195352877

在了解了区域划分的原理之后,地址空间的区域调整就变得很简单了 – 要调整一个区域的大小,调整 mm_struct 中维护此区域 start 和 end 变量即可。


四、为什么会存在进程地址空间

我们上面学习了什么是进程地址空间,以及进程地址空间如何进行管理,那么为什么会存在进程地址空间呢?我们直接将数据存入物理内存不好吗?为什么还要耗费时间和空间创建虚拟地址空间以及页表呢?这时候就需要引入进程地址空间的优势了,进程地址空间主要有如下三方面的优势。

1、进程地址空间保证了数据的安全性。

我们为每一个进程都创建一个进程地址空间,然后通过页表来关联虚拟内存与物理内存,这样当我们用户对某一进程的虚拟内存越界访问或者非法读取与写入时,页表或操作系统可以直接进行拦截,从而保证了内存中数据的安全。

2、进程地址空间可以更方便的进行不同进程间代码和数据的解耦,保证了进程的独立性。

对于互不相关的两个进程来说,它们都拥有自己独立的地址空间以及页表,页表会映射到不同的物理内存上,磁盘代码和数据加载到内存中的位置也不同,一个进程数据的改变不会影响另一个进程;

对于父子进程来说,由于子进程的 mm_struct 和 页表 是通过拷贝父进程得到的,所以二者指向同一块物理内存,共用内存中的同一份代码和数据,但即使是这样,父进程/子进程在修改数据是也会发生写时拷贝,不会影响另一个进程,保证了进程的独立性。

3、进程地址空间让进程以统一的视角来看待磁盘代码以及各个内存区域,使得编译器也能够以相同的视角来进行代码的编译工作。

对于进程来说,各个进程都认为自己的数据被放置在对应的区域,比如代码区、全局数据区,但是物理内存实际上是可以非规律存储的;

对于磁盘中的程序以及编译器来说,编译器也是以进程地址空间的规则来进行编译的,所以磁盘中的可执行程序内部也是有地址的,且此地址也是虚拟地址;所以,当我们的程序被加载到内存变成进程后,不仅程序中的各个数据会被分配物理地址,程序的内部同时也存在虚拟地址,使得CPU在取指令进行运算时,拿到的下一条指令的地址也是虚拟地址,这样CPU也可以以 虚拟地址 -> 页表 -> 物理地址 的方式来统一执行工作。

注:严格来说,磁盘中程序内部的地址叫做逻辑地址,但是在上面我们就说过,对于Linux来说,虚拟地址、线性地址、逻辑地址是一样的,都是虚拟地址。


五、进程地址空间区域的严格划分

我们上面讲的地址空间的区域划分其实是一种粗略的划分,严格的区域划分如下:image-20221117204726059

其中,我们之前熟悉的代码段、全局数据区、栈区、堆区、共享区,再加上一个命令行参数将变量被统称为用户空间,在32位操作系统下,这部分空间占总空间的3/4,即3G;剩下的1G属于内核空间。

注:我们今天讲的进程地址空间其实只将了一部分,其中还有很多比较复杂的细节我们没有涉及,比如页表分级、缺页、命中等等,这部分内容我们会在后面学习文件系统以及多线程的时候慢慢补充。


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

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

相关文章

[附源码]Python计算机毕业设计java高校社团管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

GitCode / 1024程序员开源挑战赛(10.23-11.14)

目录 csdn也有云计算了 这个挑战赛&#xff0c;主要是向大家宣布了&#xff0c;咱们csdn也有自己的云计算了&#xff01; 比较有特色的 云容器 云IDE 猿如意 也是有个有特色的工具&#xff0c;可以试用下。​编辑 问题 csdn也有云计算了 这个挑战赛&#xff0c;主…

0097 弗洛伊德算法,马踏棋盘算法

import java.util.Arrays; /* * 弗洛伊德算法 * 1.和迪杰斯特拉算法一样&#xff0c;弗洛伊德算法也是一种用于寻找给定的加权图中顶点间最短路径的算法 * 2.迪杰斯特拉算法用于计算图中某一顶点到其他顶点的最短路径 * 弗洛伊德算法计算图中各个顶点之间的最短路径 * …

IT就业专业为什么要选择大数据技术应用?

IT就业专业为什么要选择大数据技术应用&#xff1f;目前大数据领域从业人员的薪资高涨幅空间大&#xff0c;大数据人才供不应求。各大数据开发方向&#xff0c;数据挖掘、数据分析和机器学习方向&#xff0c;大数据运维和云计算方向。 一、大数据技术应用发展前景好&#xff1…

物联网协议MQTT

物联网协议MQTT 1.MQTT简介 MQTT(消息队列遥测传输)是ISO 标准(ISO/IEC PRF 20922)下基于发布/订阅范式的消息协议。它工作在 TCP/IP协议族上&#xff0c;是为硬件性能低下的远程设备以及网络状况糟糕的情况下而设计的发布/订阅型消息协议&#xff0c;为此&#xff0c;它需要一…

必考设计模式

文章目录一、单例模式&#xff08;创建型&#xff09;1、饿汉式2、懒汉式3、双重检验锁&#xff08;DCL&#xff09;4、sync.once实现单例二、工厂模式&#xff08;创建型&#xff09;1、简单工厂模式2、工厂方法模式3、抽象工厂模式&#xff08;暂时不写&#xff09;三、装饰模…

高通SDX12:SFE(shortcut-fe)软加速驱动效果调测

背景 USB转PHY RTL8153不支持高通IPA硬加速,所以采用SFE软加速 调试设备为基于Cat.6通信模组的整机 SFE软加速前:UXM环境实际测速100Mbps,设备内部sirq 87% SFE软加速驱动调测 SFE驱动代码路径:sdx12-ap\shortcut-fe\shortcut-fe SFE驱动编译文件路径:sdx12-ap\poky\m…

阿里云ACP考试内容是什么?考试时间是什么时候?

对于现在的人来说&#xff0c;网络就是帮助自己了解世界的好帮手、就是让自己生活得更方便的好工具&#xff0c;这样一来&#xff0c;市场就需要大量的人才来满足需求&#xff0c;相对应的岗位也逐渐增多。于是就有大批的大学生在填报志愿的时候&#xff0c;选择IT专业&#xf…

使用Docker发布部署C# .NET core WebApi到服务器

1、启用Docker支持 如果我们使用vs2022新建WebApi项目的时候需要勾选 启用Docker &#xff1a; 如果没有勾选或者使用VS019创建的项目&#xff0c;可以在项目右键 添加 docker支持 2、发布运用程序 接下来开始发布程序&#xff0c;右键点击项目 发布 提示在哪里发布内容&am…

什么?console.log打印出的数据不对?

背景 都怪我年轻不懂事&#xff0c;调试代码只会用console.log。那么&#xff0c;就在今天&#xff0c;出事儿了&#xff01; 看图说话。上面的111和222后面跟的数据竟然不一致&#xff1f; 在我的认知中&#xff0c;JSON里面的parse和stringify方法只是类型的转换啊&#xff…

深浅拷贝小整理(对象赋值请注意)

深浅拷贝小整理1. 一些基础知识 js数据类型分为基本数据类型>Number、String、Boolean、Null、Undefined和引用(对象)数据类型>Object包括有Function、Array、Date&#xff1b;基本数据类型存放在栈中&#xff0c;访问是按值访问&#xff1b;引用类型指的是对象&#xf…

痛定思痛!!!结合fidller抓包,简单介绍http请求报文和http响应报文

简单介绍http请求报文和http响应报文前言1. http请求报文的组成1.1 请求行的内容1.2 请求头的组成1.3 请求体2. HTTP响应报文组成前言 各类书上在介绍http请求报文和http响应报文时花的太过于专业&#xff0c;没有结合实际&#xff0c;当时读的时候可能是我太笨了&#xff0c;…

今天给在家介绍一篇健身俱乐部信息管理系统设计与实现

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下&#xff0c;你想解决的问…

安装包UI美化之路-nsNiuniuSkin界面在线设计引擎

一年多前&#xff0c;我们自己开发了一个用于编辑、预览、调试nsNiuniuSkin的UI界面工具&#xff0c;越来越觉得好用&#xff0c;忍不住想要分享出来&#xff01; 今天我把这个工具重新整理了一下&#xff0c;功能又完善了一些&#xff1b;下面就介绍一下这个工具的功能和使用…

深度解析:Web 3.0和元宇宙

导读:元宇宙的终极形态势必是去中心化的,而现在的网络生态并不能完全满足元宇宙去中心化的需求。一些人认为,即将到来的Web 3.0时代和元宇宙需要的网络生态高度重合。Web 3.0或许能够成为人类迈向元宇宙道路上重要的一步。 01 Web的三次技术迭代 Web 3.0通过新技术体现出来,…

蓝桥杯2022年第十三届决赛真题-围栏(求凸多边形的面积)

题目描述 这天&#xff0c;小明在造围栏。 他提前在地上 (二维平面) 打好了 n 个洞&#xff0c;这 n 个洞的位置形成了一个凸多边形。当他准备把固定围栏的木杆插进去的时候&#xff0c;突然发现自己少准备了两根木杆。 如图&#xff0c;他现在只能在这 n 个洞中选出 n − 2 …

【linux】软件管理

linux软件管理 文章目录linux软件管理桥接模式下配置虚拟机连接互联网nmcli相关命令windows和linux之间的FTPlinux中的软件包类型rpm相关命令搭建本地软件仓库测试本地仓库重新挂载仓库到http服务器上设置仓库镜像开机自动挂载dnf相关命令配置EPEL&#xff08;Extra Packages f…

学生个人网页设计作品:旅游网页设计与实现——成都旅游网站4个页HTML+CSS web前端网页设计期末课程大作业 学生DW静态网页设计 学生个人网页设计作品

&#x1f468;‍&#x1f393;静态网站的编写主要是用 HTML DⅣV CSSJS等来完成页面的排版设计&#x1f469;‍&#x1f393;&#xff0c;一般的网页作业需要融入以下知识点&#xff1a;div布局、浮动定位、高级css、表格、表单及验证、js轮播图、音频视频Fash的应用、uli、下拉…

【YSYY】DSPE-PEG-Transferrin;DSPE-PEG-TF转铁蛋白的主动靶向介绍;磷脂-聚乙二醇-转铁蛋白

产品简称&#xff1a;DSPE-PEG-Transferrin&#xff1b;DSPE-PEG-TF 中文名称&#xff1a;磷脂-聚乙二醇转铁蛋白 产品全称&#xff1a; 1,2-dipalmitoyl-sn-glycero-3-phosphoethanolamine-N-(polyethylene glycol)-Transferrin 产品外观&#xff1a;白色固体 结 构 式&a…

Kubernetes NUMA 感知

TopologyManager TopologyManager 在1.18版本中处于 Beta 状态&#xff0c;该功能支持 CPU 和外围设备&#xff08;例如 SR-IOV VF 和 GPU&#xff09;的 NUMA 对齐&#xff0c;使工作负载能够在针对低延迟优化的环境中运行。 在引入 TopologyManager 之前&#xff0c;CPU 和…