< Linux >:进程地址空间

news2024/11/16 13:56:59

目录

一、验证进程地址空间

二、感知进程地址空间的存在


一、验证进程地址空间

我们之前学的 C/C++ 程序地址空间是物理内存吗?

        答:不是物理内存,甚至叫做程序地址空间都不太准确,应该叫做进程地址空间,因此根本就不是 C/C++ 上的概念,而是操作系统上的概念、 

在 Linux 操作系统下验证进程地址空间:

在 Winodws 操作系统下无法验证进程地址空间,原因:

1、与 Windows 操作系统本身的设置有关、

2、与 Windows 操作系统所使用的编译器也有关系,编译器会对代码地址空间做调整,防止代码被恶意猜测,比如:栈随机化策略、

[LCC@hjmlcc ~]$ ls
a.out  hjm.c  process.c  test.c
[LCC@hjmlcc ~]$ ./a.out -a -b -c
Code addr           :0x40057d
Init global addr    :0x60103c
Uninit global addr  :0x601044
Heap addr           :0x812010
Stack addr          :0x7ffc3f1db3c0
Argv addr           :0x7ffc3f1db7c6
Argv addr           :0x7ffc3f1db7ce
Argv addr           :0x7ffc3f1db7d1
Argv addr           :0x7ffc3f1db7d4
Env addr            :0x7ffc3f1db7d7
Env addr            :0x7ffc3f1db7ed
Env addr            :0x7ffc3f1db7fd
Env addr            :0x7ffc3f1db808
Env addr            :0x7ffc3f1db818
Env addr            :0x7ffc3f1dbfe6
[LCC@hjmlcc ~]$ 

验证堆区和栈区的增长方向的问题:


二、感知进程地址空间的存在

        注意:使用 Linux 操作系统提供的系统调用接口 fork 创建出当前进程的子进程,若启动当前进程,那么当前进程和当前进程的子进程启动的先后顺序是不确定的,到底是谁先谁后启动,取决于 CPU 先运行了谁,通过实验可知,一般都是父进程先被启动,子进程再被启动,但并代表父进程一定会先被启动,记住即可、

#include<stdio.h>
#include<unistd.h>
int g_val=100;
int main()
{
  pid_t id=fork();//不考虑创建当前进程子进程失败的情况、
  if(id == 0)
  {
    //子进程
    while(1)
    {
      printf("我是子进程:%d,ppid:%d,g_val:%d,&g_val:%p\n",getpid(),getppid(),g_val,&g_val);
      sleep(1);
    }
  }
  else{
    //父进程
    while(1)
    {
      printf("我是父进程:%d,ppid:%d,g_val:%d,&g_val:%p\n",getpid(),getppid(),g_val,&g_val);
      sleep(2);                                                                                                                
    }                                                     
  }                                   
   return 0;                                          
}    

注意:此时父子进程读取到的普通全局变量是 同一个 变量、

现做如下修改:

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 //普通全局变量、
  4 int g_val=100;//以普通局部变量举例也是可以的、
  5 int main()
  6 {
  7   pid_t id=fork();//不考虑创建当前进程子进程失败的情况、
  8   if(id == 0)
  9   {
 10     //子进程
 11     int flag=0;
 12     while(1)
 13     {
 14       printf("我是子进程:%d,ppid:%d,g_val:%d,&g_val:%p\n",getpid(),getppid(),g_val,&g_val);
 15       sleep(1);
 16       flag++;
 17       if(flag==5)
 18       {
 19         g_val=200;
 20         printf("我是子进程,普通全局变量的值已被修改,请注意\n");
 21       }
 22     }
 23   }                                                                                                                            
 24   else{
 25     //父进程
 26     while(1)
 27     {
 28       printf("我是父进程:%d,ppid:%d,g_val:%d,&g_val:%p\n",getpid(),getppid(),g_val,&g_val);
 29       sleep(2);
 30     }
 31   }
 32   return 0;
 33 }

        由上图可知,父子进程读取到的普通全局变量的地址相同,但是读取到的普通全局变量的值不同,因此我们可知,此处普通全局变量的地址一定不是物理地址,不然肯定不会出现这种情况,虽然上述父子进程读取到的普通全局变量的地址相同,但父子进程各自读取到的普通全局变量并不是 同一个 变量,所以,此处的普通全局变量的地址一定是虚拟地址、

        我们之前在 C/C++ 中所谓的地址,都不是物理地址,都是虚拟地址;虚拟地址在 Linux 操作系统下又被称为:线性地址、逻辑地址;这三个概念在 Linux 操作系统下是一样的概念,但是不在Linux 操作系统下,是三个完全不一样的概念,这和 Linux 操作系统本身的空间布局有关、

        本节所讲的进程地址空间,本质上就是虚拟地址空间,因此本小结也可被称为:感知虚拟地址空间的存在、

        操作系统不让我们直接看到或访问物理内存的原因:不安全;内存(物理内存,不存在虚拟内存的概念,物理地址对应物理内存)是一个硬件,不能阻拦我们进行访问,只能被动的进行读取和写入;由野指针或越界等原因造成程序崩溃的情况并不是由内存(物理内存)造成的,而是由操作系统在程序与内存(物理内存)之间添加的软件层造成的、

        每一个进程在启动时,操作系统都会给其创建一个进程地址空间(虚拟地址空间),操作系统会对这若干个进程地址空间进行管理(先描述再组织);所谓的进程地址空间,其实本质上就是内核(操作系统)的一个数据结构,也存在于内存(物理内存)中,在 Linux 操作系统中,也是一个描述进程地址空间的 struct 结构体( struct mm_struct )、        

        所谓的进程地址空间其实就是操作系统通过软件的方式,给进程提供一个软件视角,使得每一个进程都认为其独占操作系统的所有资源(物理内存)、

        前面我们知道进程是具有独立性的,体现在相关的内核数据结构是独立的和进程的代码和数据是独立的;类比于一位海王同时撩三个女的(广撒网,钓大鱼),并对每一个女的说我只中意你,且画大饼说以后对你怎么怎么好……,从而使得每个女的都天真的认为我是不可替代的那个人,这个例子中,海王充当的就是操作系统OS,三个女的就是三个进程,海王画的大饼就是进程地址空间,海王画大饼的原因在于为了维护这三个女(三个进程)的独立性,互补干扰,若有交集则必然乱套、

        所谓的进程就是:进程等于加载到内存(物理内存)中的可执行程序(代码及数据)加上该进程对应的内核数据结构(该进程对应的描述该进程所使用的 struct 结构体(task_struct),其也存在于内存(物理内存)之中)的组合、

        在 Linux 内核中,每个进程都有 task_struct 结构体,该结构体中有个指针指向一个结构mm_struct (进程地址空间),我们假设磁盘上的一个可执行程序被加载到物理内存,之后,操作系统会给每一个进程构建一个页表结构(映射表),我们需要将虚拟地址空间(进程地址空间)和物理内存之间建立映射关系,这种映射关系是通过页表(映射表)的结构完成的,如下图:

// Linux 内核中的进程地址空间、
struct mm_struct
{
    struct vm_area_struct* mmap;  // list of VMAs
    ...
    ...
}

strcut vm_area_struct
{
    struct mm_struct* vm_mm;

    unsigned long vm_start;
    unsigned long vm_end;
    ...
    ...
}

磁盘中的可执行程序里是有地址的,因为,在链接阶段就是把多个目标文件和链接库通过地址链接起来,从而生成可执行程序的,因此可执行程序里面是由地址的,在该可执行程序中,包括代码区,已初始化全局数据区,未初始化全局数据区等等,这些区域在划分时,采用的不是在物理内存中的地址,采用的是相对地址(相对于整个可执行程序最开始的地址),当该可执行程序被加载到物理内存中(0x00000000 - 0xFFFFFFFF)时,

而堆区和栈区是等该可执行程序被加载到物理内存中才会存在的,

也是有区域的,在 Linux 命令行中输入:readelf -S a.out 即可查看、

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

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

相关文章

Notion插件,让你的页面有无限可能

// 你是否觉得notion的极简风格略为单调&#xff1f;是否想用notion实现更多的功能&#xff1f;是否想让notion更为便捷&#xff0c;更为多样化&#xff1f;那今天推荐的几款notion插件绝对不能错过&#xff0c;因为他们也确实不错。 // - ———byFutureForce DAO——— - 你…

把ChatGPT接入我的个人网站

效果图 详细内容和使用说明可以查看我的个人网站文章 把ChatGPT接入我的个人网站 献给有外网服务器的小伙伴 如果你本人已经有一台外网的服务器&#xff0c;并且页拥有一个OpenAI API Key&#xff0c;那么下面就可以参照我的教程来搭建一个自己的ChatGPT。 需要的环境 Cento…

让我们一起解密组播、IGMP、IGMP监听

前言&#xff1a;一直对组播这个概念迷迷糊糊&#xff0c;特别是交换机处理组播的方式&#xff0c;非常想搞懂但是懒癌发作。这几天终于耐心地看了下有关组播的资料&#xff0c;大致了解了一下同一广播域内组播的相关知识。组播占了计算机网络的一大部分&#xff0c;特别是组播…

ChatGPT 被大面积封号,到底发生什么了?

意大利数据保护机表示 OpenAI 公司不但非法收集大量意大利用户个人数据&#xff0c;没有设立检查 ChatGPT 用户年龄的机制。 ChatGPT 似乎正在遭遇一场滑铁卢。 3月31日&#xff0c; 大量用户在社交平台吐槽&#xff0c;自己花钱开通的 ChatGPT 账户已经无法登录&#xff0c;更…

举一反三学python(9)—excel基础

一、导论&#xff1a; 操作 excel 表格的Python 第三方库有openpyxl、xlrd、xlwt等&#xff0c;它们的功能都相同&#xff0c;就是语法有差异&#xff0c;今天我就带领大家学习用openpyxl模块操作实用的excel文件。 openpyxl模块为第三方库&#xff0c;首先要安装&#xff1a;p…

electron+vue3全家桶+vite项目搭建【九】集成vite-plugin-mock-server 模拟后端请求

文章目录引入1.引入依赖2.集成插件3.测试接口请求引入 后端接口出的太慢&#xff1f;问题不大&#xff0c;咱们可以借助vite-plugin-mock-server插件自己写接口&#xff0c;返回商量好的格式&#xff0c;后续联调直接切换环境即可 vite-plugin-mock-server官网 mock.js官网 …

uniapp人脸识别解决方案

APP端&#xff1a; 因为APP端无法使用uni的camera组件&#xff0c;最开始考虑使用内嵌webview的方式&#xff0c;通过原生dom调用video渲染画面然后通过canvas截图。但是此方案兼容性在ios几乎为0&#xff0c;如果app只考虑安卓端的话可以采用此方案。后面又想用live-pusher组件…

【Linux】vi编辑器——插入模式

目录 插入模式 光标移动命令 a A i I o O命令 a----------------在光标后附加文本 A----------------在文本行末附加文本 i------------------在光标前插入文本 I-------------------在文本开始插入文本 o----------------在光标下插入新行 O---------------在…

陶泓达:4.11黄金原油白银最新走势分析及操作策略!

黄金行情走势分析&#xff1a;   周一(4月10日)&#xff0c;国际金价一度跌约1%&#xff0c;重回2000美元干口下方。此前公布的美国3月非农就业数据显示劳动力市场吃紧&#xff0c;并提高了美联储5月再次加息的预期。金属公司MKS PAMP在一份报告中表示&#xff1a;“金价自20…

Doris(5):数据导入(Load)之Broker load

为适配不同的数据导入需求&#xff0c;Doris系统提供了五种不同的数据导入方式&#xff0c;每种数据导入方式支持不同的数据源&#xff0c;存在不同的方式&#xff08;异步&#xff0c;同步&#xff09; Broker load 通过Broker进程访问并读取外部数据源&#xff08;HDFS&#…

elasticsearch之DSL查询文档

目录 DSL查询分类 全文检索查询 match查询&#xff1a; multi_match&#xff1a; 精准查询 地理坐标查询 矩形范围查询 中心点范围 组合查询 elasticsearch中的相关性打分算法是什么&#xff1f; 案例——给“如家”这个品牌的酒店排名靠前一些 function score query…

ChatGPT写新闻-ChatGPT写文章

ChatGPT写新闻 ChatGPT可以用于生成新闻稿件&#xff0c;但需要注意的是&#xff0c;由ChatGPT生成的新闻稿件可能存在语义、逻辑、事实准确性等方面的问题&#xff0c;因此需要进行人工审核和编辑&#xff0c;确保其准确性。 下面是一个示例过程&#xff0c;大致了解如何使用…

GPT3.5 , InstructGPT和ChatGPT的关系

GPT-3.5 GPT-3.5 系列是一系列模型&#xff0c;从 2021 年第四季度开始就使用文本和代一起进行训练。以下模型属于 GPT-3.5 系列&#xff1a; code-davinci-002 是一个基础模型&#xff0c;非常适合纯代码完成任务text-davinci-002 是一个基于 code-davinci-002 的 InstructG…

PixiJS 文字模糊处理策略

pixijs介绍 PixiJS是一个用于创建交互式2D图形和动画的JavaScript库。它是一个快速、轻量级、易于使用的库&#xff0c;可以在WebGL和Canvas上运行。支持WebGL和Canvas两种渲染方式。WebGL是一种基于OpenGL的3D图形API&#xff0c;可以在GPU上进行高效的图形渲染。Canvas是一种…

基于神经辐射场NeRF的SLAM方法

随着2020年NeRF[1]的横空出世&#xff0c;神经辐射场方法&#xff08;Neural Radiance Fields&#xff09;如雨后春笋般铺天盖地卷来。NeRF最初用来进行图像渲染&#xff0c;即给定相机视角&#xff0c;渲染出该视角下的图像。NeRF是建立在已有相机位姿的情况下&#xff0c;但在…

Android kotlin (仿淘宝app收藏)用RecyclerView(androidx+BRVAH3.0.6)实现单选/多选/全选/反选/批量删除功能

文章目录 一、实现效果二、引入依赖三、实现源码1、实体类2、适配器3、提示框(关闭和确定)4、视图实现一、实现效果 二、引入依赖 在app的build.gradle在添加以下代码 implementation com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0

使用采集工具,轻松获取目标受众的数据,让您的市场营销更加精准

【数据采集神器】使用采集工具&#xff0c;轻松获取目标受众的数据&#xff0c;让您的市场营销更加精准&#xff01; 在当前这个信息化社会中&#xff0c;数据已经成为了企业发展和市场营销的必要手段。企业需要通过数据来了解市场的需求&#xff0c;了解自己产品的竞争优势&a…

你真的懂docker吗?25个试题,学过你就来

前言&#xff1a;遇到不会的&#xff0c;答案偷偷放在评论区了哦~ 1.什么是Docker A 虚拟机 B 半虚拟化技术 C 开源的应用容器引擎 D 后端软件 2. 如何搜索Nginx镜像 A docker search nginx B docker rm nginx C doc…

剑指 Offer II 024. 反转链表(经典题型)

时间是伟大的作者&#xff0c;她能写出未来的结局。 ——卓别林 目录 题目描述&#xff1a; 方法1&#xff1a;迭代法&#xff08;翻指针&#xff09; 方法2&#xff1a;头插法 方法3&#xff1a;递归法 题目描述&#xff1a; 给定单链…

【工作感悟】老程序员总结的四条工作经验教训

文章目录前言1. 不要做小需求2. 要做大需求3. 定期同步工作进度4. 项目结束&#xff0c;主动复盘总结前言 想来从事互联网工作已经很多年了&#xff0c;已经从当初的懵懂少年逐渐退化成老油条。刚毕业的时候&#xff0c;真是个愣头青&#xff0c;什么都不懂&#xff0c;也什么…