进程地址空间+环境变量

目录

环境变量

进程地址空间

理解虚拟地址空间

进程地址空间区域划分

虚拟内存和物理内存建立联系

深刻理解虚拟地址空间


环境变量

当我们需要使用一个物品的时候,首先要先找到这个物品。同样的,当要运行一个程序(指令)时,要做的第一件事情就是先找到这个程序(指令)。

小测试,打开下图窗口,输入我想打开的程序:

新建个文件夹,将QQ快捷方式添加进去,将这个路径新增到环境变量中。

 再次输入my_qq,就能从刚刚添加的路径下找到qq并运行了。

在上述的测试中,经过环境变量的配置后,当再次输入my_qq时,就可以找到该程序并运行了。

在linux下中更容易观察环境变量的作用,我们知道像pwd/cd等等这样的命令实际上就是一个个写好的程序,但是它们为什么可以直接运行,而我们自己写程序就要加上路径呢?下面试着配置环境变量,让我们的程序也能不加路径直接运行。

对比./mycode(./当前路径)执行和mycode执行。向PATH中添加了mycode后就能不加路径直接运行了。

 环境变量常用命令:

echo: 显示某个环境变量值
export: 设置一个新的环境变量
env: 显示所有环境变量
unset: 清除环境变量
set: 显示本地定义的shell变量和环境变量

测试下export和env


环境变量的组织方式

 命令行的三个参数介绍:
 

 linux下的测试:

argv数组中存放的是命令后面根的一个个选项,argc变量记录的是数组中的元素个数。

 char* env[]

env表中存放的是一个个环境变量,获取环境变量的三种方式有:getenv、char* env[i]、extern char**environ。

 extern char** environ

 getenv

进程地址空间

先来看一组代码,逻辑也很简单,fork()创建进程后,父子进程共享后面的代码。利用id不同的返回值让父子进程分流。它们都访问一个全局变量,在子进程中做下手脚,5秒后修改全局变量的值。

执行结果: 

进程间要保持独立性,也就是说子进程修改了val后,不能影响父进程,父子进程得到不同的val可以接受。但是从上述的执行结果来看,父子进程访问的val地址都是一样的,从一个地址访问,得到的却是不同的结果,那么只能说明val的地址不是物理地址而是虚拟地址。

理解虚拟地址空间

站在操作系统“管理者”的角度上,手下的进程数不过来,作为老板而言,“画饼”就是必备技能,如果真的把全部的资源给了某一个进程,那么就会出现很大的麻烦,假设每个进程访问的都是物理地址,在上述案例中,进程间的独立性就被破坏了。基于这样的原因,操作系统给每个进程画了一个“饼”,这个饼就是进程地址空间,有了这个饼,你就会安心勤快的工作,当你真的有些需求的时候,我会实实在在的分配给你一些资源,但是你想让我把许诺的饼全部兑现给你,是不可能的。综上所述,每个进程都认为自己是独享系统资源的,坚信大饼早晚都是自己的。

作为操作系统,也要管理好上述提到的虚拟地址空间,先描述,在组织。地址空间的本质,就是内核的一种数据结构。每个进程都会得到一个用这个数据结构描绘的大饼,开始努力的打工。

进程地址空间区域划分


 如上图所示,是在32位平台下编址的过程,每个地址由32个0或者1表示,从32个全0到全1一共有2^32个地址。用字节描述空间大小,每个地址占4个字节。这也是在32位平台下,一个指针的大小占4个字节的原因。

 空间有了,接下来就是如何去合理的使用,我们知道这些空间不是胡乱用的,而是被划分车了一个个模块,那么接下来要谈论的就是区域划分:
 

观察上图,空间区域的划分,实际上就是用【区域起始地址,区域结束地址】来描述的。那么我们平时在栈或者堆上用空间时,就是在扩大栈或者堆区的区域。释放空间时,就是在缩小栈或者堆区,也就是在缩小对应的区域。也就是说,区域调整实际上就是在修改各个区域的end和start

虚拟内存和物理内存建立联系

对于上述内容了解后,还差一个较为关键的环节,就是虚拟地址和物理地址是如何建立联系的,在这个过程中就要提到一个叫做页表的东西,它具体是什么这里暂时不谈,暂时知道它可以在虚拟地址和物理地址间能建某种映射即可:

回到开头谈论的问题,子进程修改了全局变量后,父子进程访问到相同的val地址,却拿到了不同的数据。此时在看这个问题,本质上每个进程都有一个操作系统给画的饼,也就是进程地址空间,当子进程没修改数据前父子进程通过页表实际上找到的是同一块物理空间,但是当子进程要对数据修改时,操作系统会先将数据进行拷贝,将数据进行分离,再更改页表的映射,使得父子进程访问不同的val。

 

操作系统为了保证进程间的独立性,通过页表、地址空间、让不同的进程映射到不懂的物理内存处。

小总结:
●给每个进程分配虚拟地址空间而不让它们直接访问物理内存的原因是防止一些非法操作,保证安全。

●进程地址空间的存在,保证了进程间的独立性。当不同的进程访问同一个数据时,如果不发生修改这些进程就访问同一块物理空间,如果一方要修改,这时就会引发写时拷贝来保证进程间的独立性。

●每个进程地址空间的区域划分规则是一样的,编译器也遵循这样的规则。

深刻理解虚拟地址空间

理解了上述的内容,在来思考我们编写的代码是怎样运行的:实际上磁盘上的可执行程序在没有加载到内存时,内部就已经有地址了。虚拟地址空间这套规则不单单是操作系统遵守,编译器也是会遵守的。当编译器对代码进行编译时,就是按照虚拟地址空间的方式对代码和数据进行编址,这一套地址是虚拟地址。当程序加载到内存中后,还会天然的得到一套物理地址。也就是说当一个程序加载到内存上时,已将有了两套地址。物理地址确定数据和代码在内存中的位置,虚拟地址用来在程序内部跳转(函数调用之类的)。

 如上图所示,cpu的几板斧:取指令、分析指令、执行指令。cpu取到的地址是程序内部的虚拟地址,这套地址的编址方式是和进程地址空间一致的,所以在通过进程地址空间找到在页表中的映射,在找到物理地址,通过物理地址锁定函数的位置,进而继续执行,反复重复上述的动作,直至该程序运行完。

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

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

相关文章

大公司为什么禁止SpringBoot项目用Tomcat?

前言 在SpringBoot框架中,我们使用最多的是Tomcat,这是SpringBoot默认的容器技术,而且是内嵌式的Tomcat。同时,SpringBoot也支持Undertow容器,我们可以很方便的用Undertow替换Tomcat,而Undertow的性能和内…

低功耗技术——流水线设计(加法器和乘法器)

文章目录前言一、流水线1、16bit加法器2、无符号4bit乘法器3、编写一个4bit乘法器模块,并例化该乘法器求解c12*a5*b二、降低FPGA功耗1、静态功耗2、动态功耗前言 2023.3.31 今天学习降低功耗的一些方法 一、流水线 电路最高工作频率:取决于最长的组合逻…

Windows下的详细Git安装

网址链接: Githttps://git-scm.com/ 下载后得到这个程序: 这里它给出的是使用Vim, 我改成的是VSCode: 第一种是让 Git 自己选择,名字是 master ,但是未来也有可能会改为其他名字; 第二种是我们自行决定&a…

大文件上传时如何做到秒传?

本文已经收录到Github仓库,该仓库包含计算机基础、Java基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模式、架构、校招社招分享等核心知识点,欢迎star~ Github地址 大家好,我是大彬~ …

Selenium基础篇之Select下拉列表选择

文章目录前言一、页面准备二、场景三、设计1.引入库2.启动浏览器实例3.访问本地演示html文件4.定位到select标签5.选择橘子🍊5.1 通过索引5.2 通过value值5.3 通过text值6.强制等待7.结束webdriver进程结果前言 大家好,我是空空star,本篇给大…

ChatGPT火出圈,80%的设计师无事可做

自从疫情过后,设计行业开始变得很凌乱。很多同行开始打价格战,设计岗位逐渐演变成了一种新型的流水线。在我国,不管什么行业,到最终都会演变成饱和状态。用金融理论来说:供不应求,就赚钱,供过于…

STM32学习(十二)

软件定时原理 使用纯软件(CPU死等)的方式实现定时(延时)功能。 不精准:函数调用压栈进栈需要耗费额外的时间;流水线使得程序执行时间不确定。CPU死等。 定时器定时原理 使用精准的时基,通过…

【大数据之Hadoop】二、Hadoop生产集群搭建之完全分布式集群

1 运行准备 (1)准备3台客户机(关闭防火墙、设置静态IP和主机名称) (2)安装JDK,配置环境变量 (3)安装Hadoop,配置环境变量 (4)配置集群 (5)单点启动 (6)配置ssh (7)群起并测试集群 2 编写集群分发脚本xsync 集群分发脚本 在/hom…

OpenGL | 渲染带透明通道的2D精灵

一、Alpha测试 Alpha 测试的基本原理为:当绘制一个片元时,首先检测其 Alpha 值,若 Alpha 值满足要求,就通过测试,绘制此片元;否则丢弃此片元,不进行绘制。 glEnable(GL_ALPHA_TEST)&#xff1b…

基于springboot实现私人健身与教练预约管理系统【源码+论文】

基于springboot实现私人健身与教练预约管理系统演示开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7 数据库工具:Navicat11 开发软件:eclipse/myeclipse/idea M…

举一反三学python(2)—函数应用

Con_Info ["王伟(男),河南郑州, 137****8331","杨秀娟(女),陕西西安, 138****4117","刘子豪(男),河北廊坊, 136****2964","李发魁(男),河南洛阳, 139***3297","王小花(女),山西太原, 138****0042",] 要求对上述文本数据解析…

main主函数参数解析

默认的main函数参数 int main(int argc, char *argv[]) {// 主函数的代码逻辑return 0; }其中,int 是主函数的返回值类型,主函数执行完后会返回一个整数值给操作系统,通常返回值为 0 表示程序正常结束,非 0 的返回值表示程序运行…

【Spring6】资源操作:Resources

8、资源操作:Resources 8.1、Spring Resources概述 Java的标准java.net.URL类和各种URL前缀的标准处理程序无法满足所有对low-level资源的访问,比如:没有标准化的 URL 实现可用于访问需要从类路径或相对于 ServletContext 获取的资源。并且缺…

配置案例丨EtherCAT转Profinet网关连接凯福科技总线步进驱动器

西门子S7-1200/1500系列的PLC,采用PROFINET实时以太网通讯协议,需要连接带EtherCAT的通讯功能的伺服驱动器等设备,就必须进行通讯协议转换。小疆GW-PN-ECATM系列的网关提供了,快速可行的解决方案。GW-PN-ECATM支持两种实时以太网通…

关于SpringBoot项目的jar包使用命令执行无法读取到外部logback配置文件的问题解决

如题。 在SpringBoot配置了logback管理日志,application.yml配置的logback配置文件相关如下: logging:config: classpath:logback-spring.xml将项目打成jar包,在jar包同级目录下创建config文件夹,并复制了resources文件夹下的配置…

Ubuntu22.04部署Kubernetes集群(亲测可用)

本文将使用kubeadm在Ubuntu22.04上部署k8s集群,kubeadm 是官方社区推出的一个用于快速部署kubernetes 集群的工具,用于快速部署Kubernetes 集群。 虚拟机准备 下载ubuntu22.04镜像,使用vmware部署三台ubuntu22.04虚拟机并配置静态ip和主机名…

第一个Vue程序

第一个Vue程序 <body> <!--view层 变成了一个模板--> <div id"app">{{message}} </div><!--导入vue.js--> <script src"https://cdn.jsdelivr.net/npm/vue2.5.16/dist/vue.min.js"></script> <script>va…

蓝桥杯3月刷题集训-A 【枚举模拟】Day3

蓝桥杯3月刷题集训-A 【枚举&模拟】Day3 文章目录蓝桥杯3月刷题集训-A 【枚举&模拟】Day3一、扫雷二、含2天数一、扫雷 我们首先读取输入中的方格图&#xff0c;将其保存在一个二维数组 grid 中。然后&#xff0c;遍历方格图中的每一个方格&#xff0c;对于每个空白方格…

Java设计模式-观察者模式

1 概述 定义&#xff1a; 又被称为发布-订阅&#xff08;Publish/Subscribe&#xff09;模式&#xff0c;它定义了一种一对多的依赖关系&#xff0c;让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时&#xff0c;会通知所有的观察者对象&#xff0c;使他们…

pandas基本应用记录

查询行数和列数 data.describe() 查询前3行数据 data.head(3) 打印第几行第几列 data.loc[index, cloumn_name ] 分组统计 不带行索引 data.groupby( column_1 )[ column_2 ].apply(sum) 去除含有NAN数据行/列 df df.dropna() # default: axis0, howany 意思是只要…