当前位置: 首页 > article >正文

【Linux】进程的概念--程序地址空间(2)

  1. 语言级别的地址

以前我们在学习C语言指针的时候,会打印地址,会有内存级别的内存。
观看一段代码
所以语言级别的地址,都是虚拟地址,并不是真实的物理地址。
打印一个是虚拟的,打印全部都是虚拟的,全部打印出来的这个空间,不是真实的内存。它叫虚拟地址空间。
在Linux地址下,这种地址叫做 虚拟地址 /线性地址
我们在用C/C++语言所看到的地址,全部都是虚拟地址!物理地址,用户一概看不到,由OS统一管理
OS必须负责将 虚拟地址 转化成 物理地址

  1. 认识进程地址空间

进程在自己执行的时候,进程自己会认为自己独占系统资源(事实上并不是)
举个例子:
所以 进程地址空间(虚拟地址空间)就是操作系统给每一个进程画的大饼。
操作系统画的饼(进程地址空间),也是需要被管理的。
操作系统管理的本质就是:先描述再管理。
所以操作系统内核就有一种数据结构 mm_struct来管理每个进程的进程地址空间。
mm_struct,能描述进程地址空间的每一个属性。
地址空间的本质就是:内核的一种数据结构(mm_struct)

  1. mm_struct

以32位机器为例子
从虚拟地址要通过页表映射,找到物理地址,然后到内存中找对应的数据.
以上都是操作系统帮我们做的
虚拟地址都是连续的地址空间,所以虚拟地址也叫线性地址.
每个进程的都有自己的虚拟进程地址空间,都需要通过页表映射到真实的物理地址.
每个进程都看不到自己的物理内存,只知道自己的虚拟内存,然后操作系统通过页表映射到真实的物理地址,供进程调用数据.
  1. 为什么存在地址空间&&页表

4.1.变相保护操作系统

如果让进程直接访问物理内存,万一越界或者非法访问了怎么办呢?
所以直接让进程访问物理内存很不安全,万一修改到系统内存里面的数据咋办?
万一读取到系统内存的数据,是不是就隐私泄漏了呢?
所以页表不仅仅是用来映射物理地址的,还能检查地址访问是否合法.我们对物理内存做非法访问的时候就会被操作系统拦截.
所以虚拟地址空间和页表的存在是为了变相保护操作系统.

4.2.保证了进程独立性

上面我们写过一个代码,父进程创建了子进程,子进程一段时间后修改了全局变量的值,此时当我们去打印这个全局变量的值和对应的地址的时候,就会发现一个问题,为什么打印的地址一样而值却不一样?
此时我们就知道了,打印的这个地址是虚拟地址.是通过页表映射到物理地址的.
所以就很好的解释了为什么.打印的地址一样而值却不一样.

写时拷贝的问题

父进程创建子进程,可以认为子进程是父进程哪里拷贝过来的,一开始其实子进程和父进程的全局变量通过页表映射到的是同一块物理内存,但是当我们尝试写入或者修改的时候,操作系统就会在内存重新找一块内存空间,然后进行数据拷贝,更改页表映射,然后让进程进行修改.这种技术就叫做写时拷贝.是为了保证进程的独立性.两个进程互相不影响.
所以操作系统为保证进程的独立性,做了很多工作,通过地址空间,通过页表,让不同的进程,映射到不同的物理内存处.可以更加方便的进行进程和进程的数据代码解耦.保证进程独立性.

4.3.让编译代码和进程执行统一看待虚拟地址空间

当一个可执行程序在磁盘的时候,程序里面有地址吗? 有的
你不要认为只有操作系统会遵守虚拟地址空间,编译器也要遵守!
编译器在编译代码的时候,就是按照虚拟地址空间的方式对我们的代码和数据进行编址的!
所以我们在编写到代码的时候需要选择32位还是64位编译,编译出来的地址是4字节和8字节.这里32位和64位说的就是按照32位的虚拟地址空间还是64位的虚拟地址空间,进行代码和数据的编址.
逻辑地址还有其他的实现方案,所以 逻辑地址 != 虚拟地址
在Linux中:逻辑地址的实现方案和虚拟地址编址差不多,非常相似,所以有时候可以直接将逻辑地址直接填进页表的左边,当成虚拟地址.

总结:

虚拟进程的另一个作用:
让进程以统一的视角,来看待进程对应的代码和数据等各个区域,方便使用.
方便编译器也以统一的视角来进行编译代码.
因为规则是一样的.


http://www.kler.cn/a/2245.html

相关文章:

  • SpringBoot核心:自动配置
  • ffmpeg翻页转场动效的安装及使用
  • 基于MindSpore NLP的PEFT微调
  • 使用 AI 辅助开发一个开源 IP 信息查询工具:一
  • 单调栈基础用法
  • 【机器人】机械臂位置、轨迹和转矩控制概要
  • 投稿指南【NO.7】目标检测论文写作模板(初稿)
  • nodejs+vue校园超市小卖部零食在线购物商城系统
  • Postman接口与压力测试实例
  • 计算机网络-DNS和域名关系
  • 运行YOLOv8实现识别
  • 微信小程序根据CODE获取用户open_id
  • TCP三次握手/四次挥手
  • C语言例程:学生成绩管理程序
  • 「Vue面试题」vue要做权限管理该怎么做?如果控制到按钮级别的权限怎么做?
  • define,typedef,inline 的区别
  • nginx 快速入门
  • IDEA一键构建Docker镜像
  • WPF UpdateSourceTrigger属性
  • 这一次,吃了Redis的亏,也败给了GPT
  • 冒泡 VS 插入 VS 选择——谁更胜一筹?(附排序源码)
  • 【iOS】—— ARC学习
  • 学习前端day01
  • 【百面成神】Redis基础11问,你能坚持到第几问
  • 瑞萨Renesas RA2L1 开发板测评(2)--LED闪烁
  • web前端框架——Vue的特性