【Linux进程基础篇】总结 | => 进程环境变量(超详细)

--------------------------------------------------------------------------------------------------------------------------------

每日鸡汤:Never frown, even when you are sad, because you never know who is falling in love with your smile

 --------------------------------------------------------------------------------------------------------------------------------

前言

前面我们已经学习了进程的各种性质:

  • 竞争性:系统进程数目众多,而CPU资源只有少量甚至一个,所以进程之间具有竞争属性的,为了高效地完成任务,更合理竞争相关资源,便具有了优先级
  • 独立性:多程序运行需要独享各种资源,多进程运行期间互补干扰(多个程序,一个程序关闭,不影响另一个程序功能)
  • 并行:多个进程在多个CPU下分别,同时进行运行,这称为并行
  • 并发:多个进程在一个CPU下采用进程切换的方式,在一段时间内,让多个进程都需要得以推进。

一:并发的理解

        多个进程在一个CPU上采用进程切换的方式运行,所以当一个进程被调度到CPU上运行,若在一个时间片内运行完毕,则将该进程释放销毁,若在一个时间片时间内仍然没有运行完毕,则会采用进程切换的方式(根据优先级将其放入到等待队列相应的优先级链表当中),即排队这就是基于进程切换的时间片轮转的调度算法。

排队(优先级):一个进程从CPU上剥离下来的,该进程放到等待队列。这就是要维护两个队列的原因。

1.1:时间片

时间片(Timeslice)是操作系统中用于实现多任务处理的一种机制。在分时系统中,CPU的时间被分割成许多小的片段,称为时间片。每个进程或线程会被分配一个时间片,在这段时间内它可以独占使用CPU资源。当这个时间片用完后,操作系统会暂停当前进程,并将控制权交给下一个等待执行的进程,这样就实现了多个进程看似同时运行的效果。

 时间片轮转调度算法

        时间片轮转调度算法(Round Robin Scheduling)是一种常见的基于时间片的调度策略。在这种算法下,每个进程都会获得一个固定长度的时间片来执行。如果在这个时间片结束时进程还没有完成其工作,那么它就会被中断,放入队列的末尾,等待下一次被调度。这种方式可以确保所有进程都能得到公平的CPU时间。

        时间片的长度对系统的性能有直接影响。如果时间片太短,会导致频繁的上下文切换,增加开销;如果时间片太长,则可能导致响应性变差,因为其他进程需要等待更长时间才能得到CPU时间。因此,选择合适的时间片长度对于优化系统性能至关重要

1.2:上下文进程切换

1.2.1:寄存器

在谈上下文切换时要先说一下有关寄存器的理解

因为CPU有许多寄存器,那么就有两个问题:

  1. 为什么函数返回值,会被外部拿到呢?
  2. 系统如何得知我们的进程当前执行到哪行代码了?

问题一:为什么函数返回值,会被外部拿到呢?

看代码汇编:

return a;        //汇编语言:mov eax 10

即: 返回值是通过CPU内寄存器拿到的。

问题二:系统如何得知我们的进程当前执行到哪行代码了?

CPU内有一个计数寄存器PC。

程序计数器PC[eip](CPU内部寄存器):记录当前程序正在执行指令的下一行指令的地址。

因为PC寄存器保存当前程序正在执行指令的下一行指令的地址。即通过PC寄存器可以随时知道当前程序运行的位置。这样系统就能够得知我们当前进程执行代码的位置。

CPU内部有着一整套寄存器:

通用寄存器:eax ebx ecx edx ...

栈帧结构寄存器:ebp esp eip ...

状态寄存器:status ...

........

1.2.2:上下文切换 

 那既然有那么多的寄存器,那么寄存器在计算机当中扮演什么样的角色呢?

=> 提高效率,进程的高频数据放入寄存器中。

即,CPU内的寄存器里面保存的是进程相关的数据,来对数据进行访问和修改

故:CPU寄存器里面保存的是进程的临时数据——也就是进程的上下文数据

引用一个小故事加深理解

进入大学,军队机构从大学内选拔兵士,你非常幸运的被选拔上了。选拔上之后就要去军队机构报道进入军队。但是进入军队之前还要去学校的院长办公室告诉校长保存我的学籍。当兵之后要回到学校继续学习。首先就要先到校长办公室来开启你的学籍情况(避免已经上了一年多了,但是你的学籍还被封密保存的情况)。

同理进程

进程 ——> 在CPU运行一个时间片完毕后进程没有执行 完——> 将进程当前位置的上下文数据[寄存器]保存好 ——> 当再次运行该进程的时候,会根据上下文数据[寄存器]找到上次没运行到的位置接着运行。

 所以上下文切换

  1. 进程在从CPU离开的时候,要将自己的上下文数据保存好,甚至带走。【保存的目的,未来都是为了恢复】。
  2. 进程在被切换的时候,要有两个阶段——1.保存上下文;2.恢复上下文)一般是指在操作系统中用来指定操作系统运行环境的一些参数.
  3. 第二次运行该进程时,会接着第一次运行该进程的所保存的最后的位置。

而在寄存器上含有关于寄存器的属性变量。

寄存器在CPU上,而在PCB内部的属性中的某一个“变量”属用来描述寄存器的各种属性的结构体。

二:认识几个环境变量

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

2.1:PATH

为什么写完一个可执行程序后将其运行要./mycmd,而mycmd则是错误的。

发现问题:并没有找到mycmd的命令。

通过 which 指令找搜索路径:

可发现which pwd,能找到pwd指令路径/usr/bin/pwd。

但是which mycmd,该命令没有在(/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/alin/.local/bin:/home/alin/bin)内部中。那么这一串路径到底是什么呢?

看PATH环境变量?

一模一样!!! 

这就引出了PATH环境变量的概念了。

PATH:Linux系统的指令默认搜索路径,即输入一串命令,首先要在PATH内部的一大串路径中的各个子路径去寻找(子路径与子路径之间用:分割)

 echo $PATH 查看PATH内部的路径情况

那么怎样才能直接输入 mycmd,运行当前可执行程序呢。这就需要对PATH环境变量做修改(两种方法)。

  • PATH=/Home/alin/test 覆盖PATH内部的路径
  • PATH=$PATH:/home/alin/test 给PAHT增加一个默认路径路径

对于直接覆盖PATH内部的路径,是不建议的。覆盖完之后,会导致很多指令都不可用了。虽然退出xshell后重新登录会恢复,但还是很冒失麻烦。

给PAHT增加一个默认路径路径(mycmd):

增加了之后,直接输入 mycmd就会执行该可执行文件。 

2.2:HOME

环境变量HOME:查看当前用户家目录

  • echo $HOME root用户输出 /root
  • echo $HOME 普通用户输出 /home/普通用户的名字

cd $HOME 进入家目录

2.3:SHELL

SHELL是一个环境变量,通常用于指定用户默认使用的 shell 程序。在 Unix 和类 Unix 系统(如 Linux 和 macOS)中,常见的 shell 包括 bashzshshksh 等。

我们是如何知道当前使用的是哪一个shell呢?

那么,SHELL环境变量保存的是shell当前版本的可执行程序

直接输入 echo $SHELL来查看当前用户的默认SHELL

2.4:HISTSIZE

HISTSIZE是一个环境变量,用于控制 shell 历史记录中存储的命令数量。这个变量通常在 bash和其他类似的 shell 中使用。

 即,就是用来记录历史命令的。

输入:echo $HISTSIZE

2.5:env指令

查看所有的环境变量

 输入 env 命令查看所有的环境变量

如何一个环境变量呢?getenv函数

查看getenv函数用法:man getenv 命令

 用法:getenv("环境变量")

在mycmd.c文件:

查看运行结果:

所以:因为有了环境变量的存在,我们的系统就具备了认识当前用户是谁的能力,只要认识当前用户是谁,就可以和文件属性的拥有者、所属组做对比,继而判定你有没有读和写的能力。

三:环境变量

3.1:环境变量的理解

环境变量是系统提供的一组name=value形式的变量,不同的环境变量有不同的用户,通常具有全局属性。

 环境变量在系统启动的时候就已经有了。

那么全局属性到底是什么?

3.2:全局属性(命令行参数)

在理解全局属性之前要谈一个命令行参数

平时在我们写的 main函数内部含有三个参数。agrc,argv,env。

int main(int argc, char* argv[], char* env[])
{// ...
}// argc:int类型
argv:指针数组
env:指针数组

char* argv[]:指针数组。内部有 argc 个元素。

并且发现是在Linux命令行上写的指令。

./mycmd -a -b -c <==> "./mycmd -a -b -c" <==> 以空格为分割[bash做的打散]:"./mycmd" "-a" "-b" "-c"

在argv向量表内部

  • argv[0] = "./mycmd"
  • argv[1] = "-a"
  • argv[2] = "-b"
  • argv[3] = "-c"

 那么Linux系统内bash为什么要这样干(打散)? => 为指令工具、软件等提供命令行选项的支持!

 比如以 ls 指令为例:

  • ls -a
  • ls -l
  • ls -a -l -d

即,通过不同的选项实现不同的功能。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>int main(int argc, char *argv[], char* env[])
{if(argc!=2){printf("Usage:%s -[a/b/c/d]\n",argv[0]);return 0;}if(strcmp(argv[1],"-a")==0){printf("功能一[-a]\n");}else if(strcmp(argv[1],"-b")==0){printf("功能二[-b]\n");}else if(strcmp(argv[1],"-c")==0){printf("功能三[-c]\n");}else if(strcmp(argv[1],"-d")==0){printf("功能四[-d]\n");}else{printf("default功能\n");}return 0;
}

第三个参数 char* env[]【环境变量列表】 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main(int argc, char* argv[], char* env[])
{int i = 0;                                                                                            for(; env[i]; i++)                                                         {                                                                          printf("env[%d] => %s\n",i, env[i]);                                   }                                                                          return 0;                                                                 }

运行mycmd程序

发现env指针数组内存储的是全部的环境变量

当main函数无参的时候还有另一种方式查看环境变量(environ):

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>int main()
{//无参调用环境变量extern char** environ;int i=0;for(; environ[i]; i++){printf("environ[%d] = %s\n",i,environ[i]);}return 0;
}

运行结果(正常显示出环境变量):

 总结:

C/C++一共有两张核心向量表

  • 第一张表:命令行参数表【命令行选项】
  • 第二张表:环境变量表【环境变量】

运行该程序时,一定会先将这两张表传过去。

即:我们所运行的进程都是子进程,bash本身在启动的时候会从操作系统的配置文件中读取环境变量信息。子进程会继承父进程交给我的所有环境变量。

所以,环境变量会从所有子进程中一直继承下去。这就是全局属性!!!

验证?

创建一个子进程:

#include <stdio.h>                                                                                        
#include <stdlib.h>
#include <string.h>int main(int argc, char* argv[], char* env[])
{pid_t id = fork();if(id==0)    //在子进程内{int i = 0;for(; env[i]; i++){printf("env[%d] => %s\n",i, env[i]);}}return 0;
}

四:本地变量&内建命令

4.1:本地变量

在命令行中直接定义

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

直接在命令行中输入:

  • a=1
  • b=2
  • ...... 

查看a变量和b变量:

  • echo $a
  • echo $b

 查看系统中所有的变量【本地变量 + 环境变量】

set 指令:

这样即可查看系统内所有的变量,包括环境变量和本地变量。 

将本地变量转换成为环境变量(export)

将本地变量a转换成为环境变量。

4.2:内建命令

Linux系统中有两批命令:

  1. 常规命令——通过创建子进程完成的
  2. 内建命令——bash不创建子进程,而是由自己亲自执行,类似于bash调用自己写的或有系统提供的函数

 看一个例子:

  1. my_data=666
  2. echo $my_data         //bash的子进程

 echo也是一条指令,它要不要创建子进程?

=> 答:不需要,它类似于一个函数,类似于是bash内部的一个函数

即,echo是一个内建命令

所以,echo指令是由bash亲自执行的。不是创建的子进程完成的。所以有能查看本地变量的功能.

相应的我们学的cd变量也是内建命令,【即可以在程序内部,修改路径】

如何验证cd内建命令呢? 使用 chdir 函数

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>int main(int argc, char *argv[], char* env[])
{sleep(30);        //留下时间操作printf("change begin:\n");if(argc==2){chdir(argv[1]); //更改成这个路径}printf("change end\n");sleep(30);return 0;
}

修改默认当前路径为根目录/ 

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

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

相关文章

PowerBI 无法拖动字段到组件上

今天在做PowerBI时发现一个奇怪的问题。 本来好好的报表&#xff0c;突然无法拖动字段到组件上。 后来在网上搜索相关问题&#xff0c;发现原因可能是因为"隐式度量值"被禁用。 就是说报表无法自动聚合计算&#xff0c;所以无法拖动字段到组件上。 正确的: 有问题…

熟食店称重计价秤软件下载 佳易王触摸屏称重自动读取重量自动计算金额系统操作教程

一、概述 【软件资源文件下载在文章最后】 熟食店称重计价秤软件下载 触摸屏称重自动读取重量自动计算金额系统操作教程 1、软件可以自动读取称的重量。2、自动计算金额并累计。不需打印条形码直接称重计算&#xff0c;节省人力和时间。 软件同时支持称重商品和条形码百货商…

十一 手写Spring框架

十一、手写Spring框架 Spring IoC容器的实现原理&#xff1a;工厂模式 解析XML 反射机制。 我们给自己的框架起名为&#xff1a;loveSpring 第一步&#xff1a;创建模块loveSpring 采用Maven方式新建Module&#xff1a;loveSpring 打包方式采用jar&#xff0c;并且引入do…

360多模态及文档理解大模型技术亮相全球机器学习技术大会,共探AI技术新前沿...

北京&#xff0c;2024年11月15日 —— 在人工智能技术飞速发展的今天&#xff0c;全球技术生态正经历着深刻的变革。2024全球机器学习技术大会&#xff08;北京站&#xff09;于11月14-15日在北京举行&#xff0c;汇聚了顶尖的AI专家、学者和行业实践者&#xff0c;共同探讨机器…

六自由度双足机器人运动控制

最近迷上了研究机器人&#xff0c;花了很多时间研究机器人的控制和交互。先后开发出来了四足四自自由度&#xff0c;四足八自由度&#xff0c;两足四自由度&#xff0c;两足六自由度机器人&#xff0c;并为他们开发了相应的大模型语音交互。通过努力&#xff0c;既锻炼了动手组…

shell脚本(2)

声明&#xff1a;学习视频来自b站up主 泷羽sec&#xff0c;如涉及侵权马上删除文章 感谢泷羽sec 团队的教学 视频地址&#xff1a;shell编程&#xff08;2&#xff09;永久环境变量和字符串显位_哔哩哔哩_bilibili 本文主要讲解临时变量和永久变量以及字符串长度截取操作。 一…

SEW MDX61B 变频器调试说明

SEW MDX61B 变频器调试说明 1、打开MOVITOOLS MotionStudio软件 2、创建新项目(可根据需求更改项目名称及保存路径) 新建完成 3、电机初始化 连接新变频器和新电机时,必须进行电机初始化。电机初始化目的为配对电机参数至变频器,简单说就是让变频器知道需要控制的是什么…

【软件测试】设计测试用例的万能公式

文章目录 概念设计测试用例的万能公式常规思考逆向思维发散性思维万能公式水杯测试弱网测试如何进行弱网测试 安装卸载测试 概念 什么是测试用例&#xff1f; 测试⽤例&#xff08;Test Case&#xff09;是为了实施测试⽽向被测试的系统提供的⼀组集合&#xff0c;这组集合包…

泛微OA 请求外部数据源

1 .oa 外部数据源配置好 取数据源名称 引用key 固定写法 datasource.A_nc datasource.数据源名称 getConnection("datasource.A_nc",xf);//A账 2 引用方式 package weaver.interfaces.jphr;import java.io.UnsupportedEncodingException; import java.sql.Conne…

深度学习基础—Bleu得分

引言 机器翻译任务中&#xff0c;通常会需要评价指标来评估机器翻译的好坏。仅通过统计翻译词在标准翻译中出现的次数这种方式很不合理&#xff0c;就需要用到Bleu得分来进行评估。 1.n-gram&#xff08;N元组&#xff09; 假设要翻译&#xff1a;Le chat est sur le tapis&am…

794: 最近对问题

解法&#xff1a; #include<bits/stdc.h> using namespace std; const int N1e33; struct P{int x,y; }a[N]; int main(int argc, char** argv) {int t,n;cin>>t;while (t--){cin>>n;for (int i0;i<n;i) cin>>a[i].x>>a[i].y;double dis,mn1…

Vue基础(1)_模板语法、数据绑定

模板语法 Vue模板语法有2大类&#xff1a; 1、插值语法&#xff1b; 功能&#xff1a;用于解析标签体内内容。 写法&#xff1a;{{xxx}}&#xff0c;xxx是js表达式&#xff0c;且可以直接读取到data中的所有属性。 2、指令语法&#xff1a; 功能&#xff1a;用于解析标签(包括…

如何清洗电水壶中的水垢亲自实践

以前看过很多生活小妙招&#xff0c;什么柠檬啊&#xff0c;白醋啊&#xff0c;土豆片啊&#xff0c;都测试过。没有用。因为自来水很硬&#xff0c;钙比较重。 钙覆盖在水壶底部&#xff0c;烧水就滋滋得响&#xff0c;而且效率变低。 昨天买洁厕剂&#xff0c;看到一种除垢…

LC13:滑动窗口

文章目录 1052. 爱生气的书店老板 这个专栏记录自己刷题碰到的有关滑动窗口的题目。 1052. 爱生气的书店老板 题目链接&#xff1a;1052. 爱生气的书店老板 第一感应该是滑动窗口可以解决的&#xff0c;随后思考并写了几个版本&#xff0c;最终版本实现结合滑动窗口一次遍历…

酒店管理系统(源码+文档+部署+讲解)

本文将深入解析“酒店管理系统”的项目&#xff0c;探究其架构、功能以及技术栈&#xff0c;并分享获取完整源码的途径。 系统概述 酒店管理系统是一款为酒店行业设计的全面管理软件&#xff0c;旨在通过集成酒店运营的各个关键环节&#xff0c;提高酒店的管理效率和客户满意…

D3开发的基本框架步骤

D3.js 是一个功能强大的数据可视化库&#xff0c;用于在网页上创建复杂的图表和交互式图形。以下是一个基本的 D3.js 开发框架&#xff0c;包括了常见的步骤和代码示例&#xff0c;帮助你快速入门。 基本框架 引入 D3.js 库设置 SVG 容器加载数据创建比例尺绘制图形添加轴添加…

正则表达式完全指南,总结全面通俗易懂

目录 元字符 连接符 限定符 定位符 修饰符&#xff08;标记&#xff09; 运算符优先级 普通字符集及其替换 零宽断言 正向先行断言 负向先行断言 正向后发断言 负向后发断言 正则表达式在线测试: 正则在线测试工具 元字符 字符描述\d 匹配一个数字字符。等价于 …

对象的初步认识

#对象可组织数据&#xff08;如统计数据的表格&#xff09; 下以表格为例 1.设计一个表格:(None为初始值设定&#xff0c;表示无) class a; ##1None ##2None 2.创建一个表格 变量a 3.对对象的属性进行赋值 变量.##1"##" 变量.##2"##" 4.查询对象中…

Linux驱动开发第1步_了解STM32MP157D

了解STM32MP157D有哪些硬件资源&#xff0c;为以后进行Linux驱动开发做准备。 STM32MP157A/D器件基于高性能双核ArmCortex-A7 32位RISC内核&#xff0c;工作频率高达800 MHz。Cortex-A7处理器&#xff1a;每个CPU具有32kbyte L1指令缓存&#xff0c;每个CPU具有32kbyte L1数据…

w039基于Web足球青训俱乐部管理后台系统开发

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以查看文章末尾⬇️联系方式获取&#xff0c;记得注明来意哦~&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0…