Linux——进程基本概念下篇

news2024/10/7 14:22:44

Linux——进程基本概念下篇


文章目录

  • Linux——进程基本概念下篇
  • 一、环境变量
    • 1.1 环境变量的定义
    • 1.2 环境变量的相关命令
    • 1.3 命令行参数
    • 1.4 本地变量和环境变量
    • 1.5 常规命令和内建命令
  • 二、进程地址空间
    • 2.1 地址空间的概念
    • 2.2 页表和MMU
    • 2.3 地址空间的作用
    • 2.4 地址空间的好处


一、环境变量

要执行一个命令,必须先要找到对应的可执行程序
为什么我们运行自己的程序的时候要加上././就是指明当前路径,要找到程序才能运行,而我们运行指令的时候却不用加呢?

因为环境变量

我们通过Xshell输入账号密码登录云服务器
在这里插入图片描述
在这里插入图片描述
为什么命令行中会自动进入我所在的家目录/home/hs 而root进入的是/root

登陆的时候,系统会进行以下步骤
1.输入用户名&&密码
2.认证
3.形成环境变量(肯定不止一个,PATH,PWD,HOME) 并且根据用户名,初始化HOME=/root,HOME=/home/XXX
4.cd $HOME

1.1 环境变量的定义

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

环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性(这就是我们使用某些程序不需要./的原因)

系统中会存在大量的环境变量,每一个环境变量都有它自己的特殊用途,用来完成特定的系统功能
注意环境变量也是OS在内存或磁盘中开辟的空间用来保存系统相关数据

常见的环境变量

PATH : 指定命令的搜索路径
HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
SHELL : 当前Shell,它的值通常是/bin/bash

1.2 环境变量的相关命令

echo $NAME // NAME:你的环境变量名称

在这里插入图片描述

env命令可以查看系统所有变量

在这里插入图片描述
我们也可以把我们自己的程序路径加到环境变量中

使用export指令

export PATH=

注意如果直接export PATH=我们自己的程序路径的话,会导致path环境变量本身具有的环境变量被覆盖
如果之前的path环境变量被覆盖,那么系统中的很多指令就会执行不了,因为没有默认寻找路径

所以不改变原有环境变量,并且添加自己的环境变量推荐以下写法

export PATH=$PATH:xxx程序所在路径 向环境变量PATH中添加xxx程序

默认更改环境变量,只限于本次登陆,重新登陆,环境变量自动被恢复 为什么?

我们直接更改的是bash进程内部的环境变量信息,每一次重新登陆,都会给我们形成新的bash解释器并且新的bash解释器自动从读取形成自己的环境变量表信息

1.3 命令行参数

main函数可以携带两个参数

int main(int argc, char* argv[])

int argc是参数的个数
char* argv[]是一个数组指针,数组的每个元素是char* 类型的指针,在linux中,通常以每个程序后面的附加选项实现,例如ls -a, ls -l,会被系统以空格为分隔符,划分成一个个字符串,依次放入argv[]中

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

shell or os自动帮我们做的,将一个大的字符串以空格作为分隔符,被分割成了若干个字串

为什么要这么干? ? ?

命令行参数,可以支持各种指令级别的命令行选项的设置,理解历史学的指令与选项之间的关系

其实main函数还有第三个参数——如何证明?

在这里插入图片描述
在这里插入图片描述
再执行env指令
在这里插入图片描述
通过对比,我们发现第三个参数是系统中的环境变量,那么这是谁传给main函数的呢?

系统启动我们的程序的时候,可以选择给我们的进程(main)提供两张表:
1.命令行参数表
⒉环境变量表

命令行启动的进程都是shell/bash的子进程,子进程的命令行参数和环境变量是父进程bash给我们传递的

父进程的环境变量信息又从哪里来?

环境变量信息是以脚本配置文件的形式存在的,每一次登陆的时候,你的bash进程都会读取vim.bash_profile配置文件中的内容,为我们bash进程形成一张环境变量表信息

如何证明?

当操作系统运行起来后,bash进程也会运行起来,同时读取配置环境变量的本地脚本,形成环境变量表,而我们的进程又大多都是bash的子进程,都会被传这张相同的环境变量表,系统环境变量具有全局属性,可以被子进程继承下去

即使不在main函数中读取第三个参数,main函数中也会有一个全局变量char** environ指向这张环境变量表
在这里插入图片描述

1.4 本地变量和环境变量

本地变量只在bash进程内部有效,不会被子进程继承下去
环境变量通过让所有的子进程继承的方式,实现自身的全局性

shell本身就是一个c程序,本地变量相当于在main中定义的一些局部变量,用set查看shell中的环境变量和本地变量,unset取消环境变量和本地变量

举个例子
在这里插入图片描述

1.5 常规命令和内建命令

Linux的命令分类

常规命令:shell调用fork函数,创建子进程,让子进程成执行的
内建命令:shell命令行的一个函数,可以直接读取shell内部定义的本地变量

echo,set,unset,pwd,umask,export等等都是内建命令,内建命令速度更快,不受环境变量影响

二、进程地址空间

2.1 地址空间的概念

在我们之前学习的C语言或者C++中,相信大家对内存应该有一定的了解,对于内存中的分布,也应该有一定的概念

在我们之前的学习中,内存中的空间分布应该是如下图中所示
在这里插入图片描述
在这里插入图片描述
但实际在内存中真的是这样分布的吗?

我们用代码进行验证
在这里插入图片描述
输出结果
在这里插入图片描述

此时能得到在父进程和子进程中g_val的地址和值是相同的,没有问题!
因为根据我们之前学的,子进程创建的时候,代码和数据是以父进程为模板创建的

我们将代码稍稍修改一下
在这里插入图片描述
输出结果
在这里插入图片描述

我们发现,父子进程,输出地址是一致的,但是变量内容不一样,这就与我们知道的知识相悖了,为什么同一个变量,同一个地址,会出现两个不同的值?

前面我们讲过如果父子进程之间的任何一方将值修改了后,OS就会进行写时拷贝,但如果发生写实拷贝的话,地址为什么还一样呢?

所以我们可以得出,此处的地址绝对不是真实的物理地址,我们平时用到的地址,都是虚拟地址/线性地址

结论

变量内容不一样,所以父子进程输出的变量绝对不是同一个变量
但地址值是一样的,说明该地址绝对不是物理地址
在Linux地址下,这种地址叫做虚拟地址
我们在用C/C++语言所看到的地址,全部都是虚拟地址!物理地址,用户一概看不到,由OS统一管理

OS必须负责将 虚拟地址 转化成 物理地址

什么是地址空间? 什么是区域划分?

OS中有物理地址,而每个进程都有一份自己的虚拟地址
每个进程都会认为自己是独享整个物理地址,它们都会以统一的方式划分自己的内存

每个进程都有自己的地址空间,而操作系统需要管理这些地址空间,如何管理?

答案很简单,先描述,再组织

所以进程地址空间本质是内核的数据类型(struct mm_struct)

struct mm_struct
{
	long code start;
	long code_end;
	long data_start;
	long data_end;
	long heap_start;
	long heap_end; //brk
	long stack_start;
	long stack_end;
	................
	//其他区域也类似
}

在这个结构体中划分好了各个区域的起始和终止位置,这就是区域划分
通过这些区域划分出不同的界限,每个进程都认为自己的mm_struct代表整个内存(地址从0x000000…000 ~ 0xFFFFFF…FFF),也就是每个进程都认为自己拥有4GB的空间

2.2 页表和MMU

OS通过页表+MMU(内置在CPU中的一个硬件)来对齐进行映射
页表负责把虚拟地址映射到物理地址

那么为什么需要页表映射,不能直接让进程地址空间访问物理内存吗?

如果我们允许进程直接访问物理内存,就很有可能访问到不属于自己的空间,所以我们需要页表来管理,如果是非法的OS就直接可以拒绝访问,所以页表中除了虚拟地址和物理地址之间的映射,还有对应的访问权限字段和是否分配&&是否有内容的字段

在这里插入图片描述

在这里插入图片描述

举个例子:

const char* p = "abcd",我们不能通过指针p修改"abcd",因为它在字符常量区,本质是OS给我们的权限只有读权限(通过页表的权限管理)

值得注意的是,当进程创建子进程前,父子进程在页表中的数据段和代码段的权限都会被OS修改成只读的,代码段只读是正常的,因为代码本身就不能被更改,但为什么数据段也要修改成只读呢?
父进程创建子进程的时候首先将自己的读写权限,改成只读,然后再创建子进程

当父进程创建子进程之后,子进程写入,此时发生写时拷贝,重新申请空间,进行拷贝,但由于权限是只读的,OS就会进行介入,此时OS发现是因为需要进行写实拷贝的情况,会进行放行,OS会修改页表,父子进程指向不同的物理内存,这是写实拷贝的策略机制

但当不是这种情况的时候,就比如上述例子中,本身字符常量区是不能修改的,此时程序出错,OS就会将请求驳回

在这里插入图片描述

2.3 地址空间的作用

为什么要有地址空间?

1. 让进程以统一的视角看待内存,所以任意一个进程,可以通过地址空间+页表可以将乱序的内存数据,变成有序,分门别类的规划好
2. 存在虚拟地址空间,可以有效的进行进程访问内存的安全检查
3. 将进程管理和内存管理进行解耦,通过页表让进程映射到不同的物理内存处,从而实现进程的独立性

2.4 地址空间的好处

我们想象一种场景:我们直接申请一块大空间,操作系统会直接全部给我了吗?如果我们没有用那么多,其他的空间不是被浪费了吗?

所以当我们在堆区申请一块空间的时候,OS会把地址空间中的heap_end加上我们申请的大小,但是却没给我们物理内存,当我们需要读取的时候,才会使用页表进行映射,得到物理空间

假设没有地址空间,那么CPU是不是只能遍历一遍物理空间才能找到该进程的起始位置?

我们可以把main函数的地址放入每个进程的地址空间(同一位置),然后CPU就访问地址空间的固定位置然后通过页表映射找到物理内存存放代码数据的位置,这样效率可以得到提升

总结
为什么要有地址空间?

1️⃣ 通过添加一层软件层,完成对进程操作的风险管理(权限管理),保护了物理内存以及各个进程的数据安全
2️⃣ 将内存申请和内存使用的概念在时间层面上划分清楚,通过地址空间完成屏蔽底层申请物理空间的过程,达到进程读写内存和OS进行内存管理操作,在软件层面上分离(你不知OS给你的内存是富裕或者是快满状态的空间)
3️⃣ 站在CPU和应用层的角度,每个进程可以看作统一使用4GB空间,而且每个空间区域的相对位置是比较确定的

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

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

相关文章

学习配置文件

1.yml的语法格式问题: 2.配置文件获取数据: Value方式: Environment: 获取自定义对象的方式: 设置get和set方法,还有toString方法。 3. 日志配置: logo的配置: 日志插件&#xff…

stable-diffusion-webui安装与使用过程中的遇到的error合集

stable-diffusion-webui1.9.2踩坑安装 1. 安装过程1.1 stable-diffusion-webui1.2 在win11或win10系统安装,需修改两个启动脚本1.2.1 修改webui-user.bat1.2.2 修改webui.bat 1.3 双击 webui-user.bat 启动脚本1.3.1 no module xformers. Processing without on fre…

MySQL主要内容

1,在表中插入数据 插入值的类型,必须和字段的类型保持一致 - 如果数据类型是字符串,必须引号引起来,数字的话,可以不加 - 插入的数据顺序和字段的顺序必须保持一致 格式一:向表中插入数据 insert in…

鸿蒙官网学习3

鸿蒙官网学习3 每日小提示项目的模块类型跨设备预览调试阶段应用的替换方式有两种 打开老的demo工程报错UIAbility 每日小提示 项目的模块类型 moduleType分为三种,只有1,2的模块支持直接调试和运行 entryfeaturehar 跨设备预览 需要手动在config.j…

电子信息制造工厂5G智能制造数字孪生可视化平台,推进数字化转型

电子信息制造工厂5G智能制造数字孪生可视化平台,推进数字化转型。5G智能制造数字孪生可视化平台利用5G网络的高速、低延迟特性,结合数字孪生技术和可视化界面,为电子信息制造工厂提供了一种全新的生产管理模式。不仅提升生产效率,…

element plus:tree拖动节点交换位置和改变层级

图层list里有各种组件,用element plus的tree来渲染,可以把图片等组件到面板里,面板是容器,非容器组件,比如图片、文本等,就不能让其他组件拖进来。 主要在于allow-drop属性的回调函数编写,要理清…

免费开源线上社交交友婚恋系统平台 可打包小程序 支持二开 源码交付!

婚姻是人类社会中最重要的关系之一,它对个人和家庭都有着深远的影响。然而,在现代社会的快节奏生活中,找到真爱变得越来越困难。在这个时候,婚恋产品应运而生,为人们提供了寻找真爱的新途径。 1.拓宽人际交流圈子 现代…

强固型车载电脑在智能轨道安全解决方案的应用

智能轨道安全解决方案 信迈提供一系列具有传感、诊断、人工智能和无线功能的车载列车解决方案。它们提供全面的可扩展性和面向未来的车辆、路旁、信号、电力、障碍物检测和数据收集功能。 应用程序: 铁路供电监控车载列车安全保护铁路轨道监控驾驶行为分析 智能车载解决方案…

Unity射击游戏开发教程:(6)在 Unity 中插入动画

原型资源替换 看到游戏立即从使用原始形状转变为准备发布游戏精灵是很奇怪的。但是,我在我的游戏中已经成功实现了游戏机制,因此我需要做的就是将原型转变为艺术品,用精灵资源替换原始形状。 原始形状是 3D,精灵是 2D,因此我必须进行一些修改才能实现转换。 我需要添加 …

普乐蛙VR航天航空体验馆VR双人旋转座椅元宇宙VR飞船

多长假来袭!!想为门店寻找更多新鲜有趣的吸粉体验?想丰富景区体验?别着急,小编为你准备了一款爆款设备——时光穿梭机,720无死角旋转!!吸睛、刺激体验,将亲子、闺蜜、情侣…

LoggerFactory is not a Logback

错误信息 LoggerFactory is not a Logback LoggerContext but Logback is on the classpath. Either remove Logback or the competing implementation (class org.slf4j.impl.SimpleLoggerFactory loaded from file:/D:/maven/repository/org/slf4j/slf4j-simple/1.7.26/slf…

Esp32-S3 进行JSON解析

之前介绍了esp32-s3的http通信,对于返回的结果进行解析也是必须的,通常我们可以使用json格式进行通信,这样即便于理解也便于取值。今天我们介绍下JSON解析。 在这里用到的库是ujson,代码如下,将如下代码保存到设备即可 import micropython import json from json import …

C++笔记:C++中的重载

重载的概念 一.函数重载 代码演示例子&#xff1a; #include<iostream> using namespace std;//函数名相同&#xff0c;在是每个函数的参数不相同 void output(int x) {printf("output int : %d\n", x);return ; }void output(long long x) {printf("outp…

TiDB 6.x 新特性解读 | Collation 规则

对数据库而言&#xff0c;合适的字符集和 collation 规则能够大大提升使用者运维和分析的效率。TiDB 从 v4.0 开始支持新 collation 规则&#xff0c;并于 TiDB 6.0 版本进行了更新。本文将深入解读 Collation 规则在 TiDB 6.0 中的变更和应用。 引 这里的“引”&#xff0c;…

小程序线多点路图绘制

需求 当接口返回一连串地图坐标&#xff0c;需要根据这些坐标串联起来&#xff0c;形成一个线路图&#xff08;本次使用步行导航线路图&#xff09;。 思路 首先优先想到使用小程序Map组件的polyline属性去进行展示。但是我们发现直接使用该属性进行坐标绘制画出来的数据都是…

李沐56_门控循环单元——自学笔记

关注每一个序列 1.不是每个观察值都是同等重要 2.想只记住的观察需要&#xff1a;能关注的机制&#xff08;更新门 update gate&#xff09;、能遗忘的机制&#xff08;重置门 reset gate&#xff09; !pip install --upgrade d2l0.17.5 #d2l需要更新import torch from tor…

10.MMD 室内场景导入背景视频和灯光

导入背景视频 1. 导入人物和场景 场景是Akali’s room&#xff0c;可以在墙壁上添加视频 先添加主场景 2. 修改视频文件格式 在背景里选择导入背景视频文件 需要将mp4视频格式转化为AVI格式 方法一 先将视频导入格式工厂 点击配置 将视频编码改成DivX 再开始处理 …

高效率Python开发工具PyCharm v2024.1——更新AI Assistant功能

JetBrains PyCharm是一种Python IDE&#xff0c;其带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具。此外&#xff0c;该IDE提供了一些高级功能&#xff0c;以用于Django框架下的专业Web开发。 立即获取PyCharm v2024.1正式版(Q技术交流&#xff1a;909157416&…

利用Spring中的SchedulingConfigurer实现数据库配置化定时任务

目录 1.利用Scheduled来实现传统的定时任务 2.两者的区别 3.Spring中的SchedulingConfigurer来拓展定时任务的灵活性 1&#xff09;UrTaskConfig 2&#xff09;TaskMain 3&#xff09;BaseTask 4&#xff09;效果 &#xff08;1&#xff09;插入配置定时任务的sql语句 …

参数传递 的案例

文章目录 12 1 输出一个int类型的数组&#xff0c;要求为&#xff1a; [11,22,33,44,55] package com.zhang.parameter; //有关方法的案例 public class MethodTest3 {public static void main(String[] args) {//输出一个int类型的数组&#xff0c;要求为&#xff1a; [11,…