Linux基础4-进程5(程序地址空间详解)

上篇文章:Linux基础4-进程4(环境变量,命令行参数详解)-CSDN博客

本章重点:

1 重新理解c/c++地址空间

2 虚拟地址空间

一. c/c++地址空间

地址空间布局图:

 运行下列代码,进行观察

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

int global_value = 100;
int main()
{
  pid_t id = fork();
  if(id < 0)
  {
    printf("fork error!\n");
    return -1;
  }
  else if(id == 0) //子进程
  {
    int cnt = 0;
    while(1)
    {
      printf("子进程,pid:%d ppid:%d | global_value:%d,&global_value: %p\n",getpid(),getppid(),global_value,&global_value);
      sleep(1);
      cnt++;
      if(cnt == 10)
      {
        global_value = 1234;
        printf("子进程已经修改了全局变量!\n");
      }
    }
  }
  else 
  {
    //父进程
    while(1)
    {
      printf("父进程,pid:%d ppid:%d | global_value:%d,&global_value: %p\n",getpid(),getppid(),global_value,&global_value);
      sleep(2);
    }
  }
  return 0;
}

        我们定义一个全局变量,创建父子进程。让他们打印各自的全局变量值和其地址,然后让子进程修改其全局变量,观察父子进程各自的全局变量和其地址

运行结果如下

可以看到,子进程修改全局变量后,父子进程全局变量的地址相同但是值却不相同!这是为什么呢?

地址没变:说明这里使用的地址不是物理地址,我们C语言所使用的地址不是物理地址而是虚拟地址(逻辑地址)

我们所打印出来的地址空间排布,都是虚拟地址。所以上面的地址分布图是虚拟地址空间

OS访问变量时候,必须要通过虚拟地址找到其物理地址才能访问

二. 理解虚拟地址空间

每一个进程都会认为自己占有所有的系统资源,每当需要的时候就向操作系统申请。

地址空间的本质:是内核中的一种数据结构 mm_struct。与PCB类似

struct mm_struct
{
    char* when;
    char* who;
    char* targrt;
    char* sum;
    ..
    ..
    ..
}

我们通过管理mm_struct进而管理每一个进程的虚拟地址空间。使用mm_struct描述每一个进程的虚拟地址,再用链表将其连接起来就能够管理

虚拟地址空间

1 地址空间描述的基本空间是字节

2 以32位操作系统为例,每一个虚拟地址空间具有 2^32 B = 4GB  个字节

3 每一个字节都代表唯一的地址,所以一共能够表示 2^32个地址

000000000 00000000 00000000 00000000

000000000 00000000 00000000 00000001

.

.

11111111 11111111 11111111 11111110

11111111 11111111 11111111 11111111

所以我们只需要用 2^32个数字用于表示每一个字节的区域即可

虚拟地址空间通过类似下列代码进行调整各区域的大小

struct mm_struct
{
  unit32_t code_start,code_end;    //代码区
  unit32_t data_start,data_end;    //常量区(数据段)
  unit32_t heap_start,heap_end;    //堆区
  unit32_t stack_start,stack_end;  //栈区
  // ......
};

//分配地址
*mm = malloc(struct mm_struct)
*mm->code_start=0x1111 1111    //区域的起始地址
*mm->code_end= 0x1211 1111     //区域的结束地址
//起始地址和结束地址的中间部分称为虚拟空间

*mm->data_start=0x1300 0000
*mm->data_end= 0x1400 0000

//堆栈区的调整,本质就是修改各个区域的start和end
//我们使用malloc new 申请堆空间,定义局部变量,函数调用-> 就是扩大堆栈区的空间
//函数调用完毕,free空间->就是缩小栈区,堆区空间

*mm->heap_start=0x1400 0001
*mm->heap_end= 0x1500 0000

*mm->stack_start=0x7ffff 7fff
*mm->stack_end= 0x8fff ffff

我们在PCB中定义一个指针指向 mm_struct,这样就能给进程分配进程地址空间

三. 虚拟地址空间与内存,磁盘之间的关系

如上图,每一个进程都有自己的进程地址空间,进程地址空间通过页表映射到物理内存中。

进程运行时候,将磁盘中的数据加载到内存中,然后通过页表与进程地址空间形成映射关系。

每一个进程都有自己的进程地址空间

每一个进程都有自己独立的进程地址空间,他们都通过页表和内存之间的映射找到对应的代码和数据。

这样就能够保证进程之间的独立性,统一使用相同的虚拟地址空间而不会相互干扰

这也说明了为什么我们最开始的时候,父子进程的全局变量的地址相同而值不同的原因!

尽管他们的虚拟地址空间相同,他们通过页表映射到物理内存是不相同的!

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

4.1 进程直接访问物理内存,如果发生非法访问咋办?

如果发生了非法访问,这样是非常不安全的。因为会访问和干扰到其他进程的数据

操作系统通过页表可以拦截进程的非法操作,从而达到保护操作系统的目的!(每一个进程都要遵守这一规则)

4.2 虚拟地址空间的存在,可以保证进程之间的独立性

如上图,最开始父子进程的全局变量其实是一个(即通过页表映射到的物理地址相同)。

然后当子进程修改全局变量的时候,会发生写时拷贝

写实拷贝:父子进程任何一方尝试修改(写入)相同物理内存的数据,OS会先进程数据拷贝,然后更改修改进程的页表映射关系。然后再让进程进行修改

写实拷贝能够保证不同进程的数据进程分离从而达到了进程之间的独立性

进程 = PCB + 进程对应的数据代码

我们知道:每一个进程的PCB都是独立的,现在每一个进程对应的数据代码也是独立的

这说明:进程是独立的

4.3 方便进程和编译器以统一的视角,来看待对应的代码和数据的各个区域

我们知道 进程的 mm_struct(进程地址空间)和 C语言程序中的逻辑地址,二者的规则是一样的!

这样一来,我们只要编译完代码就能够直接使用。

我们编译完的可执行程序,在没有加载到内存中的时候,有没有逻辑地址呢?        有!

虚拟地址空间,操作系统要遵守这个规则,编译器也要遵守这个规则。        编译器编译代码的时候就是通过地址空间的方式进行编址的!

五.下章重点:进程控制

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

本地连接IP地址的自主设置指南‌

在数字化时代&#xff0c;网络连接已成为我们日常生活和工作中不可或缺的一部分。无论是家庭网络还是企业网络&#xff0c;正确配置IP地址是确保网络畅通无阻的基础。IP地址&#xff0c;即互联网协议地址&#xff0c;是网络中每个设备的唯一标识。掌握如何自主设置本地连接的IP…

对 fn.apply(this, arguments) 的使用还在疑惑?快进来看看它的设计含义及常见使用场景吧~

&#x1f64c; 如文章有误&#xff0c;恳请评论区指正&#xff0c;谢谢&#xff01; ❤ 写作不易&#xff0c;「点赞」「收藏」「转发」 谢谢支持&#xff01; 背景 近期在研究高阶函数封装的过程中&#xff0c;看到 fn.apply(this, arguments) 的出镜率非常高&#xff0c;而如…

【ReactPress】React + antd + NestJS + NextJS + MySQL 的简洁兼时尚的博客网站

ReactPress 是使用React开发的开源发布平台&#xff0c;用户可以在支持React和MySQL数据库的服务器上架设属于自己的博客、网站。也可以把 ReactPress 当作一个内容管理系统&#xff08;CMS&#xff09;来使用。 前言 此项目是用于构建博客网站的&#xff0c;包含前台展示、管理…

Pycharm远程调试deepspeed!可用!

本人写代码的习惯就是一定是要从别人优秀的代码中调试学习的&#xff0c;直接运行看的话&#xff0c;可能知道了大概的逻辑但是缺无法知道细节的话&#xff08;参数的含义或者某某数据格式类型&#xff09;&#xff0c;可能对整体代码逻辑的把控不是狠好&#xff0c;所以还是从…

Redis 中 Bitmap 原理和应用

Bitmap Redis中的Bitmap&#xff08;位图&#xff09;是一种较为特殊数据类型&#xff0c;它以最小单位bit来存储数据&#xff0c;我们知道一个字节由 8个 bit 组成&#xff0c;和传统数据结构用字节存储相比&#xff0c;这使得它在处理大量二值状态&#xff08;true、false 或…

基于 STM32 的天气时钟项目中添加天气数据的网络获取功能

基于 STM32 的天气时钟项目中添加天气数据的网络获取功能&#xff0c;您需要确保您的开发环境具备网络连接能力。这里以 ESP8266 Wi-Fi 模块为例&#xff0c;详细说明如何实现网络获取天气数据的功能。 1. 硬件连接 连接 ESP8266 模块 请参考以下连接方式&#xff0c;将 ESP82…

mysql-springboot netty-flink-kafka-spark(paimon)-minio

1、下载spark源码并编译 mkdir -p /home/bigdata && cd /home/bigdata wget https://archive.apache.org/dist/spark/spark-3.4.3/spark-3.4.3.tgz 解压文件 tar -zxf spark-3.4.3.tgz cd spark-3.4.3 wget https://raw.githubusercontent.com/apache/incubator-celeb…

【Spring】体系结构

Spring框架至今集成了多个模块&#xff0c;这些模块分布在数据访问/集成&#xff08;Data Access/Integration&#xff09;、Web层、面向切面的编程&#xff08;Aspect Oriented Programming&#xff0c;AOP&#xff09;模块、植入&#xff08;Instrumentation&#xff09;模块…

软件缺陷等级评定综述

1. 前言 正确评估软件缺陷等级&#xff0c;在项目的生命周期中有着重要的作用&#xff1a; 指导缺陷修复的优先级和资源分配 在软件开发和维护过程中&#xff0c;资源&#xff08;包括人力、时间和资金&#xff09;是有限的。通过明确缺陷的危险等级&#xff0c;可以帮助团队合…

Linux:vim命令总结及环境配置

文章目录 前言一、vim的基本概念二、vim模式命令解析1. 命令模式1&#xff09;命令模式到其他模式的转换&#xff1a;2&#xff09;光标定位&#xff1a;3&#xff09;其他命令&#xff1a; 2. 插入模式3. 底行模式4. 替换模式5. 视图模式6. 外部命令 三、vim环境的配置1. 环境…

Obsidian的Git插件设置配置全流程 -- 简单的电脑端多平台同步方案及常见问题

Obsidian的Git插件设置配置全流程 -- 简单的电脑端多平台同步方案及常见问题 参考文章引言1. git 介绍及安装2. git 本地配置及远程仓库链接3. obsidian 的 git 插件4. 常用的使用场景和对应的命令4.1. 本地仓库已推送到远端&#xff0c;如何在另一个电脑上第一次同步4.2 多端同…

【优选算法篇】微位至简,数之恢宏——解构 C++ 位运算中的理与美

文章目录 C 位运算详解&#xff1a;基础题解与思维分析前言第一章&#xff1a;位运算基础应用1.1 判断字符是否唯一&#xff08;easy&#xff09;解法&#xff08;位图的思想&#xff09;C 代码实现易错点提示时间复杂度和空间复杂度 1.2 丢失的数字&#xff08;easy&#xff0…

Redis(3):持久化

一、Redis高可用概述 在介绍Redis高可用之前&#xff0c;先说明一下在Redis的语境中高可用的含义。   我们知道&#xff0c;在web服务器中&#xff0c;高可用是指服务器可以正常访问的时间&#xff0c;衡量的标准是在多长时间内可以提供正常服务&#xff08;99.9%、99.99%、9…

高亚科技签约酸动力,助力研发管理数字化升级

近日&#xff0c;中国企业管理软件资深服务商高亚科技与广东酸动力生物科技有限公司&#xff08;以下简称“酸动力”&#xff09;正式签署合作协议。借助高亚科技的8Manage PM项目管理软件&#xff0c;酸动力将进一步优化项目过程跟踪与节点监控&#xff0c;提升研发成果的高效…

大模型领域最值得看的 9 本新书,找到了

在人工智能革命的浪潮中&#xff0c;程序员们正站在技术变革的最前沿。本书单精选了关于人工智能在各行业应用的最新著作&#xff0c;从医疗诊断到金融风控&#xff0c;从智能制造到智慧城市&#xff0c;全面展现AI如何重塑行业生态&#xff0c;推动社会进步。通过阅读这些书籍…

加入GitHub Spark需要申请

目录 加入GitHub Spark需要申请 GitHub Spark 一、产品定位与特点 二、核心组件与功能 三、支持的AI模型 四、应用场景与示例 五、未来展望 六、申请体验 加入GitHub Spark需要申请 GitHub Spark 是微软旗下GitHub在2024年10月30日的GitHub Universe大会上推出的一款革…

Rust移动开发:Rust在iOS端集成使用介绍

iOS调用Rust 上篇介绍了 Rust移动开发&#xff1a;Rust在Android端集成使用介绍, 这篇主要看下iOS上如何使用Rust&#xff0c;Rust可以给移动端开发提供跨平台&#xff0c;通用组件支持。 该篇适合对iOS、Rust了解&#xff0c;想知道如何整合调用和编译的&#xff0c;如果想要…

【月之暗面kimi-注册/登录安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞 …

2024 CSS保姆级教程四

CSS中的动画 CSS动画&#xff08;CSS Animations&#xff09;是为层叠样式表建议的允许可扩展标记语言&#xff08;XML&#xff09;元素使用CSS的动画的模块​ 即指元素从一种样式逐渐过渡为另一种样式的过程​ 常见的动画效果有很多&#xff0c;如平移、旋转、缩放等等&#…

[C++11] Lambda 表达式

lambda 表达式&#xff08;Lambda Expressions&#xff09;作为一种匿名函数&#xff0c;为开发者提供了简洁、灵活的函数定义方式。相比传统的函数指针和仿函数&#xff0c;lambda 表达式在简化代码结构、提升代码可读性和编程效率方面表现出色。 Lambda 表达式的基本语法 在…