Linux进程概念 (下) 地址空间

news/2024/7/5 4:46:01

前言

中篇讲了进程为什么要有优先级,以及环境变量和通过代码获得环境变量 本篇主要讲解什么是地址空间 , 地址空间是怎么设计的?为什么要有地址空间?


程序地址空间

先看下图 

 验证上图的正文代码至堆的地址是不是从低地址向高地址增加栈相反。我们用下面这段代码试试

 #include <stdio.h>
    2 #include <stdlib.h>
    3 
    4 int unval;
    5 int val = 10;
    6 
    7 
    8 
    9 
   10 int main()
   11 {
   12     printf("code addr: %p\n", main);
   13     printf("init global addr: %p\n", &val);
   14     printf("uninit global addr: %p\n", &unval);
   15     char *heap_mem = (char*)malloc(10);
   16     printf("heap addr: %p\n", heap_mem);
   17     int a = 10;
   18     printf("test stack addr: %p\n", &a);                                                                                                                                                                    
   19                                                                                                                           
   20     return 0;                                                                                                             
   21 }                       

 

从上图看地址确实是如上图的所画那样从低地址向高地址增加。 

我们再看一段代码运行结果

int main()
{
    pid_t id = fork();
    if(id < 0){
        perror("fork");
        return 0;
    }
    else if(id == 0){ //child,子进程肯定先跑完,也就是子进程先修改,完成之后,父进程再读取            
    g_val=100;
        printf("child[%d]: %d : %p\n", getpid(), g_val, &g_val);
    }else{ //parent
        sleep(3);
        printf("parent[%d]: %d : %p\n", getpid(), g_val, &g_val);
    }
    sleep(1);
    return 0;
}

请看下面的视频

虚拟地址

从视频得出的结论,怎么和以往的C语言和C++不一样 在语言中同一个变量,值怎么可能会有两个? 下面我就要引出一个概念:虚拟地址

虚拟地址

1.1 什么是虚拟地址?

首先我先讲一个故事

在一家公司里有小明小美和小红三个员工,有一天老板对这个三个员工分别单独在没有其他人情况下许下了承诺(PUA)"你今年努力干工作年底给你调职加薪"

许下承诺后三个员工就继续干工作了,但是他们都以为自己是唯一一个被老板叫去谈话的且认为自己独享这福利待遇。

故事到这里先暂停一哈

我们先引出几个相对应的概念

这里的老板就是操作系统

三个员工就是进程

调职加薪就是虚拟地址 ->(物理内存)

看到这里你就会明白了 所有的进程都会有一份自己的虚拟地址。之前讲的程序地址空间是不准确的,准确来说应该是进程地址空间

总结:在C/C++言语中所看到的地址,全部都是虚拟地址,物理地址用户看不到,OS按照地址空间这种结构设计出虚拟地址,然后将虚拟地址映射到物理内存中。

1.2地址空间又是如何设计的?

Linux源代码 内核数据结构如下图设计地址空间 感兴趣的自己可以去官网下载源代码看看

地址空间用结构体定义出来,再用数据结构进行管理(先描述后组织)然后把它的指针放在task_struct PCB 这个结构体里。

1.3为什么要有地址空间?

如果进程直接访问物理地址空间会怎么样?

上图是以前计算机设计时 磁盘越过OS 直接访问内存,现在计算机在OS中增加虚拟地址 然后通过页表映射到物理内存中。看下图

加入了虚拟地址和页表映射机制后,你的写程序出现野指针问题OS直接就把你的进程给你杀掉了,它其实是运行了得。在运行那一瞬间 OS发现你的虚拟地址通过映射到物理内存中和之前正在进程访问的是同一块物理内存地址 ,这时OS就不会把你的进程虚拟地址映射到物理内存中,直接kill。这就是程序崩溃的原因。

到这里 我们就能回答刚才的问题了 为什么同一个地址会有两个不同的值看下图

父进程先运行虚拟地址通过页表映射到物理内存中,子进程继承父进程的所有代码和数据

和页表(地址空间和页表每个进程都会私有一份)OS做的就是每一个进程页表,映射到物理内存不同区域中,然后写时拷贝 就改变了子进程的val值。

 没看懂在看一次

重新理解挂起

加载本质就是创建进程,那是不是非得要把程序所有代码和数据加载到内存中?

答案不是。

一个大型单机游戏 小的几十个G 大一点的200G 内存才多大?内存要满了OS将进程的内核结构创建出来 ,一个游戏有不同模块

OS很聪明将这些模块分批加载 当然也可以分批换出,换出同时就成了挂起状态。


http://lihuaxi.xjx100.cn/news/2033614.html

相关文章

JVM体系

JVM是一种虚拟的计算机&#xff0c;它模拟了一个完整的硬件系统&#xff0c;并运行在一个完全隔离的环境中。这意味着JVM可以看作是一个在操作系统之上的计算机系统&#xff0c;与VMware、Virtual Box等虚拟机类似。JVM的设计目标是提供一个安全、可靠、高效且跨平台的运行环境…

神经网络:卷积神经网络中的BatchNorm

一、BN介绍 1.原理 在机器学习中让输入的数据之间相关性越少越好&#xff0c;最好输入的每个样本都是均值为0方差为1。在输入神经网络之前可以对数据进行处理让数据消除共线性&#xff0c;但是这样的话输入层的激活层看到的是一个分布良好的数据&#xff0c;但是较深的激活层…

如何一键抠图换背景?分享两个好用的抠图方法

在数字化时代&#xff0c;图片编辑已成为日常生活和工作中不可或缺的一部分。而智能抠图软件&#xff0c;作为近年来兴起的图片处理技术&#xff0c;正引领着图片编辑的新篇章。它利用先进的机器学习和图像识别技术&#xff0c;能够自动识别和分离图片中的主体&#xff0c;实现…

踩坑实录(Fourth Day)

今天开工了&#xff0c;其实还沉浸在过年放假的喜悦中……今天在自己写 Vue3 的项目&#xff0c;虽说是跟着 B 站在敲&#xff0c;但是依旧是踩了一些个坑&#xff0c;就离谱……照着敲都能踩到坑&#xff0c;我也是醉了…… 此为第四篇&#xff08;2024 年 02 月 18 日&#x…

题记(45)--字符串匹配

目录 一、题目内容 二、输入描述 三、输出描述 四、输入输出示例 五、完整C语言代码 一、题目内容 读入数据string[ ]&#xff0c;然后读入一个短字符串。要求查找string[ ]中和短字符串的所有匹配&#xff0c;输出行号、匹配字符串。匹配时不区分大小写&#xff0c;并且可…

2023我患上了AI焦虑

2023我患上了AI焦虑 来自&#xff1a;宝玉 原文链接&#xff1a;https://baoyu.io/blog/ai/i-am-suffering-from-ai-anxiety-in-2023 2023 年对我来说是神奇的一年&#xff0c;我意外的从一个程序员变成了一个 AI 资讯届的“网红”&#xff0c;到年底的时候我在 X 平台的阅读量…

学习数据接构和算法的第10天

题目讲解 尾插 #include <stdio.h> #include <stdlib.h> // 定义顺序表结构 #define MAX_SIZE 100 struct ArrayList {int array[MAX_SIZE];int size; // 当前元素个数 }; // 初始化顺序表 void init(struct ArrayList *list) {list->size 0; // 初始时元素个…

PostgreSQL Error Codes (PostgreSQL错误代码)

Whats PostgreSQL Error Codes PostgreSQL服务器发出的所有消息都分配了五个字符的错误代码&#xff0c; 这些代码遵循 SQL 的"SQLSTATE"代码的约定。 需要知道发生了什么错误条件的应用程序通常应该检测错误代码&#xff0c;而不是查看文本错误消息。 这些错误代码…