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

Linux环境变量进程地址空间

目录

一、初步认识环境变量

1.1常见的环境变量

1.2环境变量的基本概念

二、命令行参数

2.1通过命令行参数获取环境变量

2.2本地变量和内建命令

2.3环境变量的获取

三、进程地址空间

3.1进程(虚拟)地址空间的引入 

3.2进程地址空间的布局和理解

​3.3什么是地址空间?

3.4地址空间如何进行区域划分?

3.5进一步理解进程和进程地址空间

3.6页表的理解

四、Linux内核进程调度队列

4.1优先级

4.2活动队列

4.3过期队列

4.4active指针和expired指针

4.5总结


一、初步认识环境变量

1.1常见的环境变量

  • PATH:Linux系统下的指令命令的默认搜索路径

  • HOME:用户登录shell的默认主工作目录

  • SHELL:当前Shell,它的值通常是/bin/bash

为什么我们运行自己的可执行程序需要加./,而一些指令可以直接执行,这是因为存在环境变量PATH,它是Linux下指令的默认搜索路径,当运行一个指令时,操作系统会到PATH中去查找该指令的所在路径 ,当我们把我们可执行程序的路径添加到PATH中,也可像指令一样直接执行,不需要添加./

  • 和环境变量相关的指令
  • 1. echo: 显示某个环境变量值
  • 2. export: 设置一个新的环境变量
  • 3. env: 显示所有环境变量
  • 4. unset: 清除环境变量
  • 5. set: 显示本地定义的shell变量和环境变

1.2环境变量的基本概念

  • 环境变量是系统引入的一套name=value形式的变量,不同的环境变量具有不同的用途,环境变量具有全局属性

  • 环境变量一般是指在操作系统中用来指定操作系统运行环境的一些参数 

  • 有了全局属性这个概念,以下要引入命令行参数来解释这个概念 

二、命令行参数

2.1通过命令行参数获取环境变量

  • main函数有三个参数,int  agrc ,char*argv[ ] ,char*evn[ ]

  • 当我们在输入各种指令,运行各种程序时,本质上输入的都是一个一个的字符串,bash会根据空格将这些字符串一一划分,argc就是用来记录划分字符串的个数的,argv是一张叫作命令行参数的表(本质上是一个指针数组),里面存储的是被bash分割形成的一个个字符串的地址

  • 为什么需要命令行参数表呢?因为这样可以为我们的指令、软件、软件等提供命令行选项支持!

  • 命令行参数表是以NULL为结束的

  • 实例:通过argv查看命令行参数

  • 实例:通过命令行参数argc和agrv来进行选项的设置

  • main函数中还有一个参数evn,它对应是一张环境变量表,可以通过打印该表来查看系统的所以环境变量

  • 通过比较可以发现,子进程的环境变量和env展示出来的环境变量一模一样!这就可以解释为什么环境变量具有全局属性了!
  • 我们所运行的进程都是子进程,bash本身在启动时会从操作系统的配置文件中读取环境变量, 形成一张环境变量表,这个表会被子进程的main函数参数接收,也就是说,子进程会继承父进程交给它的环境变量,所有建立在父进程上的子进程都会有相同的一份环境变量

2.2本地变量和内建命令

  • 本地变量:只会在本bash内部有效,不会被子进程继承 

 

set可以查看所以变量(环境变量&&本地变量)

 

export可以把本地变量设置成成环境变量

 子进程中也可以查找到一份

 通过unset可清除设置的环境变量

  • 我们知道任何程序和指令在运行时都是bash的子进程,本地变量只对本bash内部有效,那么这里就有一个问题了:为什么使用echo可以显示出MY_VALUE的内容呢?
  • 这里就要再引入一个新的概念:内建命令
  1. 常规命令:通过创建子进程完成的
  2. 内建命令:bash不创建子进程,由bash自己执行,类似bash通过调用自己内部实现的函数或者系统提供的函数,比如echo、cd都属于内建命令,比如我们在cd时改变的是bash下的工作目录,并不会去改变子进程所在的目录
  3. 模拟实现一个具有cd功能的指令--chdir()系统提供的一个改变当前工作目录的函数

2.3环境变量的获取

  • 第一种就是上面演示的通过命令行的第三个参数获取
  • 第二种是通过第三方变量environ获取

  • 第三种是通过调用系统函数获取或者设置环境变量--getenv()和putenv()

三、进程地址空间

3.1进程(虚拟)地址空间的引入 

观察下面代码的运行结果:可以看到子进程对全局变量g_val1进行修改,父进程和子进程输出变量的值不一样,但是地址是一样的,说明该变量所在的地址一定不是物理地址!父子进程输出的变量在物理地址上看来也不是同一个变量!我们在用C/C++语言看到的也是虚拟地址,真正的物理地址用户是看不见到,由操作系统统一管理

  • 操作系统必须负责物理地址和虚拟地址之间的映射,那操作系统具体是如何做到的呢? 

3.2进程地址空间的布局和理解

  • 结合fork() 初步理解地址进程空间

  • 前面已经谈到,fork()创建子进程成功,会有两个返回值,给父进程返回子进程的pid,给子进程返回0。fork()之后创建的子进程,在内存中除了有一个以父进程为模板(拷贝)的pcb数据结构,还有一个从父进程拷贝下来的mm数据结构(进程地址空间)和一个页表,页表中存着变量虚拟地址和物理地址的映射关系、权限字段、判断数据在内存还是磁盘的字段,通过映射关系,可以找到虚拟地址对应的物理地址

  • 子进程刚创建的时候,在mm中数据的虚拟地址和父进程是一样的,我们打印看到的都是这个虚拟地址,子进程刚拷贝父进程的数据结构内容的时候,代码和数据都是共用的,并且数据在页表中的权限会被设置为只读

  • 由于代码是共享的,那么在fork()return前子进程被创建好了,return就会被父子进程各执行一次,又由于return的实质就是在对变量进行写入,这时候就相当于要对数据进行修改

  • 当子进程和父进程有一方要对数据进行修改,就会触发对数据的非法操作,从而发生缺页中断,此时操作系统就会重新在内存中开辟一块空间,将要修改的数据拷贝一份作修改,再重新建立映射关系,这个过程也叫写时拷贝,这样父子进程就做到了各自私有一份数据

  • 我们上面代码所展示的结果,地址一样变量值不一样,这是因为打印出来的地址是虚拟地址,子进程拷贝了父进程的数据结构内容,所以他们的虚拟地址就是一样的;变量值不一样是因为,写时拷贝后虚拟地址在页表中映射的物理地址不一样,找到的数据当然也就并不一样了。这两个原因结合就说明了我们所看到的现象

3.3什么是地址空间?

  • 地址总线排列组合形成的地址范围[0,2^32) 32根地址总线

3.4地址空间如何进行区域划分?

  • 进程地址空间本质上是描绘进程可视范围大小,在内核上他是一个数据结构对象(mm_struct),也要被操作系统管理,地址空间通过各个区域的star和end对区域进行线性(区域)划分,在一个区域的范围内,连续空间中,每一个最小单元都有地址,都可以被使用
  • 区域空间的调整,本质上就是通过调整每个区域的star和end

3.5进一步理解进程和进程地址空间

  • 目前为止,我们所说的进程,就是:进程=内核数据结构对象(pcb,mm,页表)+程序的代码和数据(可执行文件) 

  • 为什么需要进程地址空间?

  1. 让进程以统一的视角来看待内存:如果进程直接和物理地址进行交互,那么进程的pcb数据结构中就势必要存在各个数据的物理地址。一个进程的各个数据部分,在物理内存中实际是乱序的,但是有了地址空间(mm_struct)之后:代码就在代码段,数据就在数据段该在堆区的在堆区,该在栈区的在栈区同时,这些连续的虚拟地址再经过的页表映射到物理内存,这样,让进程数据地址从无序变有序,让进程以统一的视角看待物理内存以及各个运行区域,每个进程都会以为自己占有了整个系统的内存资源

  2. 拦截对内存的非法操作和异常访问:进程地址空间让我们在访问内存的时候有一个转化的过程,在这个过程中,如果我们对内存进行了非法操作和访问,那么就会被拦截,物理内存不会收到影响,进而保护了物理内存

  3. 有了进程地址空间和页表,就可以做到将进程管理模块和内存管理模块进行解耦合:进程在运行的时候不会关心操作系统是如何申请内存的,对进程的管理和对内存的申请都是由操作系统来完成,他们互不干扰!操作系统不做任何浪费时间和空间的事情,当一个进程申请了内存,但是它又不立即使这块内存的时候,就相当于占用了内存资源,这时候操作系统会采用惰性加载的方式:给该进程一个虚拟地址,但在页表中并没有实际映射的物理地址,也就是说进程看到的是已经开辟好的虚拟地址,但在物理内存上并没有真的申请到空间;当进程需要内存的时候,找不到映射的物理地址触发缺页中断,此时操作系统就会给它开辟空间,建立映射关系。从而说明了,pcb数据结构对象的创建先于可执行程序的加载

3.6页表的理解

  • 页表不仅仅有虚拟地址和物理地址的映射,还有对应的权限,当一个进程要对一个数据修改时,本质是通过虚拟地址找到对应物理内存的数据再修改,当要修改某一个数据,但是该数据在页表的所记录的权限只有rx,仅仅允许只读,那么就会修改动作就会被拦截,直接报错,程序崩溃,修改这个动作就不会被允许

  • 这也就是为什么,一个程序崩溃时,并不会影响其他进程,因为崩溃的程序在虚拟内存页表层就已经被拦截,操作系统会直接杀掉进程,进而也就不会影响其他进程的运行

  • 总结:页表存在CPU的cr3寄存器(物理地址),进程在被CPU调度和离开CPU的时候,都要带走寄存器里的数据 ,CPU在运行程序时,为了获取数据,就会通过cr3寄存器里的页表地址找到该进程的页表,页表中的虚拟地址通过映射得到物理地址,进而可以访问到物理内存,同时会根据虚拟地址和物理地址的映射权限(rwx)来决定是否能对该物理内存进行操作,如果非法操作,该请求会被拦截,操作系统会将此进程杀掉

  • 三个实例体现页表的作用

  1. 进程的挂起是如何实现的?前面说到,页表中还存在一个用来判断数据是在内存还是在磁盘中的字段,进程的挂起就是将该进程所对应的数据和代码换出到外设分区中,那么这时候操作系统只需要通过修该字段就可以知道进程是否处于挂起状态

  2. 进程的独立性:进程的独立性表现在,每个进程都有自己私有的一份数据,以及每个进程都有自己的一份mm_struct进程地址空间,这就保证了每个进程只能访问自己的进程地址空间,相互之间不得访问!也就是说,如果进程直接和物理内存打交道,那么就可能访问到其他进程的数据,但是由于进程地址空间的存在,非法访问在页表层面就会被拦截,确保了更个进程之间不会非法访问和篡改对方的数据

  3. 代码和字符常量区的数据为什么是只读的?如果这写数据本身是只读的,那么它就不可能从磁盘加载到内存中!这边的只读是在页表层面上的只读!它在页表中的权限被设置成只读,当一个进程试图修改该部分的数据,一样会被拦截

四、Linux内核进程调度队列

  • 一个CPU拥有一个runqueue 

4.1优先级

  • 普通优先级:100~139(我们都是普通的优先级,想想nice值的取值范围,可与之对应!)
  • 实时优先级:0~99(不关心)

4.2活动队列

  • 所有时间片还没结束的进程都被放在活动队列
  • 本质上是一个指针数组,数组的下标就表示优先级,从100开始
  • 调度过程
  1. 从[0,140)开始遍历,找到第一个优先级最高且非空的队列
  2. 从该队列的第一个进程开始调度运行
  3. 但由于逐一遍历数组的效率太低下了,为了提高查找非空队列的效率,可以采用位图的思想,用5*32个比特位来队列是否为空

4.3过期队列

  • 过期队列的结构和活动队列一样
  • 过期队列上放的都是时间片过期的队列
  • 当活动队列的进程都调度结束了,那么swap交换两个队列的指针,就可以对过期队列的进程进行时间片的重新计算,等待调度运行

4.4active指针和expired指针

  • active指针指向活动队列
  • expired指针指向过期队列
  • 当活动队列的进程全都调度完毕,swap交换两个指针,就相当于有了新的活动队列

4.5总结

  • 在系统当中查找一个最合适调度的进程的时间复杂度是一个常数,不随着进程增多而导致时间成本增 加,我们称之为进程调度O(1)算法

 

相关文章:

Linux环境变量进程地址空间

目录 一、初步认识环境变量 1.1常见的环境变量 1.2环境变量的基本概念 二、命令行参数 2.1通过命令行参数获取环境变量 2.2本地变量和内建命令 2.3环境变量的获取 三、进程地址空间 3.1进程(虚拟)地址空间的引入 3.2进程地址空间的布局和理解 …...

C++读取txt文件中的句子在终端显示,同时操控鼠标滚轮(涉及:多线程,产生随机数,文件操作等)

文章目录 运行效果功能描述代码mian.cppincludeMouseKeyControl.hTipsManagement.h srcMouseControl.cppTipsManagement.cpp 运行效果 功能描述 线程一:每隔n随机秒,动一下鼠标滚轮,防止屏幕息屏。 线程二:运行时加载txt文件中的…...

Android 中使用高德地图实现根据经纬度信息画出轨迹、设置缩放倍数并定位到轨迹路线的方法

一、添加依赖和权限 在项目的build.gradle文件中添加高德地图的依赖&#xff1a; implementation com.amap.api:maps:latest_version在AndroidManifest.xml文件中添加必要的权限&#xff1a; <uses-permission android:name"android.permission.ACCESS_FINE_LOCATIO…...

LeetCode从入门到超凡(二)递归与分治算法

引言 大家好&#xff0c;我是GISer Liu&#x1f601;&#xff0c;一名热爱AI技术的GIS开发者。本系列文章是我跟随DataWhale 2024年9月学习赛的LeetCode学习总结文档&#xff1b;在算法设计中&#xff0c;递归和分治算法是两种非常重要的思想和方法。它们不仅在解决复杂问题时表…...

superset 解决在 mac 电脑上发送 slack 通知的问题

参考文档: https://superset.apache.org/docs/configuration/alerts-reports/ 核心配置: FROM apache/superset:3.1.0USER rootRUN apt-get update && \apt-get install --no-install-recommends -y firefox-esrENV GECKODRIVER_VERSION0.29.0 RUN wget -q https://g…...

SQL_UNION

在 SQL 中使用 UNION 操作符时&#xff0c;被联合的两个或多个 SELECT 语句的列数必须相同&#xff0c;并且相应的列数据类型也需要兼容。这是因为 UNION 操作符会将结果组合成单个结果集&#xff0c;每个 SELECT 语句的结果行将按顺序放置在结果集中。 例如&#xff0c;如果你…...

高等代数笔记(2)————(弱/强)数学归纳法

数学归纳法的引入情景其实很简单&#xff0c;就是多米诺骨牌。 推倒所有多米诺骨牌的关键就是推倒第一块&#xff0c;以及确保第一块倒下后会带动第二块&#xff0c;第二块带动第三块&#xff0c;以此类推&#xff0c;也就是可以递推。由此我们可以归纳出所有的多米诺骨牌都可…...

模拟自然的本质:与IBM量子计算研究的问答

量子计算可能是计算领域的下一个重大突破&#xff0c;但它的一般概念仍然处于炒作和猜测的现状&#xff1f;它能破解所有已知的加密算法吗&#xff1f;它能设计出治愈所有疾病的新分子吗&#xff1f;它能很好地模拟过去和未来&#xff0c;以至于尼克奥弗曼能和他死去的儿子说话…...

Robot Operating System——带有时间戳和坐标系信息的多边形信息

大纲 应用场景1. 机器人导航场景描述具体应用 2. 环境建模场景描述具体应用 3. 路径规划场景描述具体应用 4. 无人机飞行控制场景描述具体应用 5. 机械臂运动控制场景描述具体应用 6. 自动驾驶车辆控制场景描述具体应用 定义字段解释 案例 geometry_msgs::msg::PolygonStamped …...

内网穿透(当使用支付宝沙箱的时候需要内网穿透进行回调)

内网穿透 一、为什么要使用内网穿透&#xff1a; 内网穿透也称内网映射&#xff0c;简单来说就是让外网可以访问你的内网&#xff1a;把自己的内网(主机)当做服务器&#xff0c;让外网访问 二、安装路由侠 路由侠-局域网变公网 (luyouxia.com) 安装成功如下&#xff1a; 三…...

Contact Form 7最新5.9.8版错误修复方案

最近有多位用户反应Contact Form 7最新5.9.8版的管理页面有错误如下图所示 具体错误文件的路径为wp-content\plugins\contact-form-7\admin\includes\welcome-panel.php on line 153 找到welcome-panel.php这个文件编辑它&#xff0c;将如下图选中的部分删除 删除以后&#xf…...

【第十一章:Sentosa_DSML社区版-机器学习之分类】

目录 11.1 逻辑回归分类 11.2 决策树分类 11.3 梯度提升决策树分类 11.4 XGBoost分类 11.5 随机森林分类 11.6 朴素贝叶斯分类 11.7 支持向量机分类 11.8 多层感知机分类 11.9 LightGBM分类 11.10 因子分解机分类 11.11 AdaBoost分类 11.12 KNN分类 【第十一章&…...

kafka3.8的基本操作

Kafka基础理论与常用命令详解&#xff08;超详细&#xff09;_kafka常用命令和解释-CSDN博客 [rootk1 bin]# netstat -tunlp|grep 90 tcp6 0 0 :::9092 :::* LISTEN 14512/java [rootk1 bin]# ./kafka-topics.s…...

如何检测并阻止机器人活动

恶意机器人流量逐年增加&#xff0c;占 2023 年所有互联网流量的近三分之一。恶意机器人会访问敏感数据、实施欺诈、窃取专有信息并降低网站性能。新技术使欺诈者能够更快地发动攻击并造成更大的破坏。机器人的无差别和大规模攻击对所有行业各种规模的企业都构成风险。 但您的…...

《linux系统》基础操作

二、综合应用题(共50分) 随着云计算技术、容器化技术和移动技术的不断发展,Unux服务器已经成为全球市场的主导者,因此具备常用服务器的配置与管理能力很有必要。公司因工作需要,需要建立相应部门的目录,搭建samba服务器和FTP服务器,要求将销售部的资料存放在samba服务器…...

EMT-LTR--学习任务间关系的多目标多任务优化

EMT-LTR–学习任务间关系的多目标多任务优化 title&#xff1a; Learning Task Relationships in Evolutionary Multitasking for Multiobjective Continuous Optimization author&#xff1a; Zefeng Chen, Yuren Zhou, Xiaoyu He, and Jun Zhang. journal&#xff1a; IEE…...

MySQL record 08 part

数据库连接池&#xff1a; Java DataBase Connectivity&#xff08;Java语言连接数据库&#xff09; 答&#xff1a; 使用连接池能解决此问题&#xff0c; 连接池&#xff0c;自动分配连接对象&#xff0c;并对闲置的连接进行回收。 常用的数据库连接池&#xff1a; 建立数…...

打造以太坊数据监控利器:InfluxDB与Grafana构建Geth可视化分析平台

前言 以太坊客户端收集大量数据&#xff0c;这些数据可以按时间顺序数据库的形式读取。为了简化监控&#xff0c;这些数据可以输入到数据可视化软件中。在此页面上&#xff0c;将配置 Geth 客户端以将数据推送到 InfluxDB 数据库&#xff0c;并使用 Grafana 来可视化数据。 一…...

对onlyoffice进行定制化开发

基于onlyoffice8.0源码&#xff0c;进行二次开发&#xff0c;可实现包括但不限于以下的功能 1、内容控件的插入 2、内容空间的批量替换 3、插入文本 4、插入图片 5、添加&#xff0c;去除水印 6、修改同时在线人数限制 7、内容域的删除 8、页面UI的定制化 9、新增插件开发 10、…...

使用llama.cpp 在推理MiniCPM-1.2B模型

llama.cpp 是一个开源项目&#xff0c;它允许用户在C中实现与LLaMA&#xff08;Large Language Model Meta AI&#xff09;模型的交互。LLaMA模型是由Meta Platforms开发的一种大型语言模型&#xff0c;虽然llama.cpp本身并不包含LLaMA模型的训练代码或模型权重&#xff0c;但它…...

分布式环境中,接口超时重试带来的的幂等问题如何解决?

目录标题 幂等不能解决接口超时吗&#xff1f;幂等的重要性什么是幂等?为什么需要幂等?接口超时了&#xff0c;到底如何处理&#xff1f; 如何设计幂等?幂等设计的基本流程实现幂等的8种方案1.selectinsert主键/唯一索引冲突&#xff08;常用&#xff09;2.直接insert 主键…...

设计一个推荐系统:使用协同过滤算法

设计一个推荐系统:使用协同过滤算法 在当今数据驱动的时代,推荐系统已经成为了许多在线平台(如电商、社交媒体和流媒体服务)不可或缺的一部分。推荐系统通过分析用户的行为和偏好,向用户推荐可能感兴趣的内容或产品。本文将详细介绍如何设计一个基于协同过滤算法的推荐系…...

Linux 基本指令(二)

目录 1. more指令 2. less指令(重要) 3. head指令 4. tail指令 5. date指令 (1)可以通过选项来指定格式&#xff1a; ​编辑 (2)在设定时间方面 (3)时间戳 6. cal指令 7. find指令 8. grep指令 9. alias指令 10. zip指令与unzip指令 (1). zip指令 (2). unzip指令…...

Facebook的用户隐私保护:从争议到革新

Facebook早期的数据收集方式引发了隐私担忧。平台的快速增长和用户数据的大规模收集使得隐私问题逐渐显现。尤其是在2018年&#xff0c;剑桥分析事件暴露了数千万用户数据被不当使用的问题。这一事件揭示了Facebook在数据保护方面的严重漏洞&#xff0c;引发了公众对隐私保护的…...

计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-23

计算机前沿技术-人工智能算法-大语言模型-最新论文阅读-2024-09-23 本期&#xff0c;我们对大语言模型在表情推荐, 软件安全和 自动化软件漏洞检测等方面如何应用&#xff0c;提供几篇最新的参考文章。 1 Semantics Preserving Emoji Recommendation with Large Language Mod…...

C++(学习)2024.9.20

目录 C面向对象的基础知识 this指针 概念 功能 1.类内调用成员 2.区分重名的成员变量和局部变量 3. 链式调用 static关键字 1.静态局部变量 2.静态成员变量 3.静态成员函数 4.单例设计模式 const关键字 1.const修饰成员函数 2.const修饰对象 3.const修饰成员变量…...

让AI激发创作力:OpenAI分享5位专业作家利用ChatGPT写作的案例技巧

大家好&#xff0c;我是木易&#xff0c;一个持续关注AI领域的互联网技术产品经理&#xff0c;国内Top2本科&#xff0c;美国Top10 CS研究生&#xff0c;MBA。我坚信AI是普通人变强的“外挂”&#xff0c;专注于分享AI全维度知识&#xff0c;包括但不限于AI科普&#xff0c;AI工…...

UEFI EDK2框架学习 (一)

01 Shell界面打印 执行qemu指令后 qemu-system-x86_64 -drive ifpflash,formatraw,fileOVMF.fd -nographic -net none出现shell界面 02 在UEFI shell中创建APP 创建SimplestApp文件夹以及SimplestApp.c、SimplestApp.inf cd edk2 mkdir SimplestAppuuidgen // generate …...

基于 BERT 的自定义中文命名实体识别实现

基于 BERT 的自定义中文命名实体识别实现 在自然语言处理中,命名实体识别(Named Entity Recognition,NER)是一项重要的任务,旨在识别文本中的特定实体,如人名、地名、组织机构名等。本文将介绍如何使用 BERT 模型实现自定义中文命名实体识别,并提供详细的代码分析和解读…...

中秋节特别游戏:给玉兔投喂月饼

&#x1f5bc;️ 效果展示 &#x1f4dc; 游戏背景 在中秋这个充满诗意的节日里&#xff0c;玉兔因为贪玩被赶下人间。在这个温柔的夜晚&#xff0c;我们希望通过一个小游戏&#xff0c;让玉兔感受到人间的温暖和关怀。&#x1f430;&#x1f319; &#x1f3ae; 游戏设计 人…...