Linux学习:进程(3)与 环境变量

news2024/9/21 4:31:17

目录

  • 1. 进程的优先级
    • 1.1 什么是进程的优先级
    • 1.2 优先级的具体表示与查看方式
  • 2. 进程的切换与调度
    • 2.1 切换
    • 2.2 调度
  • 3. 环境变量
    • 3.1 main参数/命令行参数
    • 3.2 什么是环境变量
    • 3.3 环境变量的使用与特性
    • 3.5 本地变量与环境变量的脚本配置文件

1. 进程的优先级

  1. 在计算机运行的过程中,有着许许多多的需要被执行的进程,而就绪状态的进程被加载到内存中的运行队列上。那么,它们之间的先后是如何区分的,它们是照申请先后的顺序排列而后执行吗?接下来,让我们对进程的新属性,进程的优先级来进行学习与了解。

1.1 什么是进程的优先级

  1. 在现实生活中,各种事物的优先级代表着这些事物所要被执行的先后顺序。而在计算机中对于进程来说,也是如此,进程的优先级决定了其被CPU执行的先后顺序。
  2. 当我们去谈论优先级的概念时,就代表有了需要我们去讨论优先级的前提与场景,进程的优先级决定着进程被CPU的执行顺序。
  3. 而当我们提及到进程的优先级时,就一定代表着CPU不能够第一时间内处理所有需要被进行的进程,或者可以说CPU的资源无法满足支持可以第一时间处理每个进程,所以,此时就需要将各个进程进行排队等待。
  4. 内存中需要被执行的进程各种各样,我们应该怎么将它们进行排队,并且需要保证排队的方式足够合理与高效,可以支持操作系统与各个进程的正常运行。

1.2 优先级的具体表示与查看方式

  1. 优先级也属于进程PCB属性中的一个,我们使用指令ps -la [进程号],可以查看到指定进程的优先级等相关信息。(PRI:priority)

在这里插入图片描述

  1. 进程的优先级表示,PCB中以int类型的变量来表示进程的优先级,其可被修改的数据范围为 [60,99],一共40个数,数值越小优先级越高,数值越大优先级越低。
  2. Linux下我们创建的每个进程的优先级默认为80,每个进程的优先级是可以被我们手动更改的,进程优先级计算判定由两部分组成old PRI + NI(nice)
  3. 我们无法直接修改PRI,需要通过修改NI从而达到间接修改PRI的效果,修改指令为renice [n] [进程号],n的取值范围为 [-20, 19],每次计算的old PRI都是从默认PRI即80开始计算的,而每次对NI的写入都是覆盖式写入。

在这里插入图片描述

  1. 当使用renice指令调整NI的范围超过[-20, 19]时,renice只会取极值不会超过NI的限制范围。

补充:为什么要对能够修改的优先级划定范围

  1. 当进程优先级的优先级可以被随意修改时,可能会因为认为的操作出现大量的高优先级的进程,这些进程会大量占用CPU的资源,甚至可能会导致原本的进程因此无法被CPU执行,导致这些进程及其卡顿甚至不能够被运行。
  2. 这些因为高优先级泛滥问题而不能够被正常执行的进程,我们称之为饥饿进程

2. 进程的切换与调度

2.1 切换

  1. CPU具体是如何处理一个个进程的,每一个进程都是在CPU上一直被执行,直到彻底执行完毕吗?
  2. 事实并给如此,Linux操作系统中进程的执行方式是以时间片进行切换,每个进程都以时间片(1ms)为单位进行轮转执行。
  1. 进程相关概念补充:
    <1> 竞争性:进程会因为优先级的不同区分先后顺序
    <2> 独立性:各个进程之间不会相互干扰,独享各种资源
    <3> 并行:计算机中有多个CPU,各个进程被分散在不同CPU上同时执行
    <4> 并发:多个进程被一个CPU通过高频进程切换得方式执行,同时得以推进
  2. 多核:CPU有一个控制器,同时拥有多个运算器
  1. CPU存在着大量的寄存器,不同种类的寄存器担任着不同的职能:
    <1> eax/ebx/ecx/edx,通用寄存器:临时性的数据保存
    <2> eds/ecs/fg/gs,段寄存器:衡量区域调用数据的区域
    <3> eip/cr0-cr4,PC指针:记录标识程序执行到的进度与位置
    <4> 程序状态字
    <5> 浮点数存储器
    <6> ebp/esp(小盒子),函数栈帧开辟相关
  2. 根据前面的了解,我们直到进程是以时间片为单位在CPU上执行的,而进程被执行时会携带着大量的自身数据,这些数据是需要交给CPU进行处理计算的,CPU获取与存储这些数据的方式就是将它们拷贝至自身的寄存器中。(寄存器不等于寄存器内容,一套寄存器可以有多套寄存器内容)
  3. 进程被切换走,中断执行的步骤:
    <1> 剥离寄存器中的核心数据数据
    <2> 将核心数据全部带走,保存至进程的PCB中,记录执行进行执行到的位置,即,保护进程的硬件上下文数据(CPU内部所有的临时数据)
  4. 进程二次切换回来,继续执行的步骤:
    <1> 恢复上下文,覆盖是写入上下文数据
    <2> 从上次执行到的位置继续执行

在这里插入图片描述

2.2 调度

  1. 操作系统按照一定的方式去执行运行队列上的各种进程,这就被称为进程的调度,不同的操作系统对于进程有着不同的调度算法。
  2. 根据操作系统应用场景的不同,按照进程调度算法的偏向不同可以分为两类:
    <1> 分时优先级:操作系统会公平的执行每个进程
    <2> 时时优先级:操作系统对于用户的请求,发送的进程会进行优先处理,高响应(车载系统)
  1. Linux操作系统O(1)调度算法:

在这里插入图片描述

  1. O(1)调度算法操作步骤 与 变量解释:
    <1> struct task_struct* queue[140]:PCB指针数组,进程的可修改优先级范围为40,此数组开放[100, 139]范围的40个下标用来存储不同优先级队列的指针
    <2> int bitmap[5]:int类型数组,其容量大小为5,有40个bit位,每一位都标识着一个优先级运行队列中是否有进程,二进制位为1代表有,0代表没有。通过这种方式,可以位运算的方法快速检测并找到需要被执行有进程的优先级队列
    <3> int nr_active:一个整形变量,标识bitmap中8组优先级队列是否仍有进程剩余,若没有值为0,若有值为非0
    <4> 运行队列中存在着两个相同的结构,分别用来标识活跃队列与过期队列,CPU只会执行活跃队列中的进程,而新进的进程只会添加至过期队列中。
    <5> 通过活跃队列与过期队列的方式,O(1)调度算法很好的规避的优先级队列的进程饥饿问题
    <6> struct q* active:执行活跃队列的指针
    <7> struct q* expried:指向过期队列的指针
    <8> 当活跃队列中的进程执行完毕,active与expried指针就会进行值交换,这样就达到了运行队列切换的效果,又因为只是指针的交换,消耗极小,效率很高

3. 环境变量

3.1 main参数/命令行参数

  1. 从初始接触编程开始我们就识得了main函数,在使用时从来没有给main函数传递过参数,可是,main函数真的没有参数吗
  2. main函数其实存在着三个可以添加的隐藏参数,接下来就让我们来进行对它们的学习
int main(int argc, char* argv[], char* env[])
{
	return 0;
}
  1. 命令行参数argvargv
    <1> argv:字符串类型的数组,执行可执行程序时,从命令行中以空格为间隔获取字符串
    <2> argv:argv字符串数组的元素个数
int main(int argc, char* argv[])
{
	int i = 0;
	for(i = 0; i < argc; i++)
	{
		printf("%s\n", argv[i]);
	}

	return 0;
}

在这里插入图片描述

  1. 我们在前面的学习中已经了解到,操作系统中的一个个指令其实都是可执行程序,而各种指令附带不同的参数选项就有不同的效果,其底层的实现就是利用了命令行参数实现的。类似操作,如下
 int main(int argc, char* argv[])                                                                                                                                                       
{
      if(argc != 2)
      {
          printf("waring Usage:\n\t./process [a~c]\n\n");
      }
      else if(strcmp(argv[1], "-a") == 0)
      {
          printf("-a usage\n");
      }
      else if(strcmp(argv[1], "-b")== 0 )
      {
          printf("-b usage\n");
      }
      else if(strcmp(argv[1], "-c") == 0)
      {
          printf("-cx usage\n");
      }
      else
      {
          printf("no usage\n");
      }
  
      return 0;
 }

在这里插入图片描述

3.2 什么是环境变量

  1. 在编程语言中的变量是我们于内存中开辟的一块空间,我们赋予这块空间名称并以此调用这块空间进行各种数据的存储与运算,变量在运行期间也可以开辟。
  2. 环境变量也是变量,同样与编程语言中变量的属性相同,不同的只是环境变量是操作系统从内存中申请,用来存放一些必要的信息资源,系统内置具有特殊用途的变量。
  3. 系统中的环境变量有许多,环境变量的命名方式通常都为大写英文字母前加特殊符号:$环境变量名,我们可以通过指令:echo [环境变量]来查看对应环境内的具体内容。

在这里插入图片描述

  1. 下面罗列几个常见的环境变量:
    <1> $PATH:存放常用资源路径的环境变量
    <2> $USER:存放当前用户名的环境变量
    <3> $PWD:存放当前所处目录路径的环境变量
    <4> $HOME:存放当前用户家目录的环境变量
  1. 我们在前面的学习中了解到,可执行程序要想运行必须要给出可执行程序的绝对或相对路径,让操作系统可以找到对应可执行程序并执行。
  2. 可是,系统中的一些自带指令为什么调用时可以不加路径声明呢,这是因为系统每次启动时bash都会在$PATH环境变量中会默认添加入,系统自带指令的所在路径,这样我们在使用这些指令时系统可以直接从环境变量中拿到自己需要的资源信息。

在这里插入图片描述

  1. 我们若想让自己编写的可执行程序像系统自带指令一样使用,有两种方法:
    <1> 像操作系统登录时每次都会检索并以以此生成环境变量的路径里添加我们的可执行程序(不推荐,开发不完备可能会污染其他文件)
    <2> 向环境变量$PATH中临时添加我们可执行程序所在的路径,退出销毁,指令如下:
PAHT=[需添加路径]:$PATH
//:$PATH不可省,否则会将原有的内容全部覆盖

在这里插入图片描述

3.3 环境变量的使用与特性

  1. main函数的第三个命令行参数char* env[],是一个字符串数组以NULL结尾,其中存储内容为父进程传递给main函数所在可执行程序的环境变量。
int main(int argc, char* argv[], char* env[])
{
	int i = 0;
	for(i = 0; env; i++)
	{
		printf("%s\n", env[i]);
	}

	return 0;
}

在这里插入图片描述

  1. 环境变量为全局属性,子进程可以继承父进程的环境变量,bash命令行解释器是我们所创建进程的父进程。
  2. 定义环境变量的方式:export [环境变量名]=[赋值]

在这里插入图片描述

  1. 子进程除开通过传递env环境变量参数列表的方式一次性获取父进程所有环境变量,我们还可以通过C语言库中函数getenv获得指定的环境变量。(stdlib.h头文件中)
//身份识别
int main()
{
	if(strcmp(getenv("USER"), "zyc") == 0)
	{
		printf("this is a limited core process\n");
	}

	return 0;
}
  1. C语言库中存在着一个第三方变量environ,此变量的是一个二级指针数组,其中以字符串指针的形式存放着bash进程中所有的环境变量。
int main()
{
	//做符号声明
	extern char** environ;
	int i = 0;
	for( i = 0; environ[i]; i++)
	{
		printf("%s\n", environ[i]);
	}
	
	return 0;
}

3.5 本地变量与环境变量的脚本配置文件

  1. 环境变量为bash定义,适用于不同应用环境具有特殊用途的信息。而系统中拥有的变量种类不止一种,还有很多其他种类。
  2. 本地变量:一种在当前bash进程内定义,不能被子进程继承只在bash内部有效的变量
  3. 定义本地变量的方式:[变量名]=[赋值],查看本地变量:echo [$本地变量]
  4. <1> 指令:set(查看所有变量,包括环境变量与本地变量)
    <2> 指令:unset(从上下文信息中移除变量)
  1. 经过前面的学习我们已经知道,环境变量是通过bash进程定义出来,我们此退出后重新登录Xshell后,之前定义的环境变量就会消失。
  2. 可是为什么bash自带的环境变量不会消失呢,其实这些环境变量并不是不会消失,而是存储在服务器磁盘中脚本与配置文件中,每次我们登录Xshell重新启动bash进程,都会导入脚本。
  3. 我们若想要让自己定义的环境变量等也可以登录加载,就可以通过在配置文件中添加定义的方式来实现。
  4. 每个用户的配置文件都不同,它们都处于当前用户的家目录下,文件名为.bash_profile,此文件又从bashrc中导入内容。
  5. 在配置文件.bash_profile中添加提示语,可以登陆时提示。

在这里插入图片描述
示例:
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

前端基础知识html

一.基础标签 1.<h1>-<h6>:定义标题&#xff0c;h最大&#xff0c;h最小 2.<font>&#xff1a;定义文本的字体&#xff0c;尺寸&#xff0c;颜色 3.<b>&#xff1a;定义粗体文本 4.<i>&#xff1a;定义斜体文本 5.<u>&#xff1a;定义文本下…

SPDZ基础使用手册(深度学习视角)

基本类型 深度学习中最常使用的便是秘密定点数sfix&#xff0c;有关定点数的高级运算协议请参阅Paper: Secure Computation With Fixed-Point Numbers. 容器类型 SPDZ的深度学习框架主要基于TensorFlow实现&#xff0c;其中使用的容器是张量Tensor&#xff0c;在库中的定义如下…

如何提bug?

很多公司都有提bug的标准&#xff0c;对于新人刚介入测试行业时&#xff0c;提bug的时候&#xff0c;描述的清晰与否就很重要&#xff0c;那一个很明朗清晰的bug应该包含那些呢&#xff1f; bug包含的要素有那些&#xff1f;&#xff08;以jira工具为例&#xff09; 1、项目名…

Parade Series - SVG Resource

iconfont https://www.iconfont.cn/?spma313x.search_index.i3.2.74e53a819tkkcG音符 <div class"form-group"><a href"Javascript:reload();" class"btn btn-icon btn-outline-light btn-block" style";"><svg t&q…

docker logs 查找日志常用命令

docker logs 是什么 docker logs 是 Docker 命令行工具提供的一个命令&#xff0c;用于查看容器的日志输出。它可以显示容器在运行过程中生成的标准输出&#xff08;stdout&#xff09;和标准错误输出&#xff08;stderr&#xff09;&#xff0c;帮助用户诊断容器的行为和排查…

Spring boot 发送文本邮件 和 html模板邮件

Spring boot 发送文本邮件 和 html模板邮件 提示&#xff1a;这里使用 spring-boot-starter-mail 发送文本邮件 和 html模板邮件 文章目录 Spring boot 发送文本邮件 和 html模板邮件一、开启QQ邮箱里的POP3/SMTP服务①&#xff1a;开启步骤 二、简单配置①&#xff1a;引入依赖…

【Linux 驱动基础】Linux platform平台设备驱动

# 前置知识 总线驱动模型简介&#xff1a; 总线是处理器与一个或者多个设备之间的通道&#xff0c;在设备模型中&#xff0c;所有的设备都是通过总线相连&#xff0c;当然也包括虚拟的 platform 平台总线。 总线驱动模型中有三要素&#xff1a; 1. 总线 /*** struct bus_ty…

RTSP应用:实现视频流的实时推送

在实现实时视频流推送的项目中&#xff0c;RTSP&#xff08;Real Time Streaming Protocol&#xff09;协议扮演着核心角色。本文将指导你通过安装FFmpeg软件&#xff0c;下载并编译live555&#xff0c;以及配置ffmpeg进行视频流推送&#xff0c;来实现一个基本的RTSP流媒体服务…

05-JavaScript对象

1. 对象 1.1 对象的相关概念 什么是对象&#xff1f; 在 JavaScript 中&#xff0c;对象是一组无序的相关属性和方法的集合&#xff0c;所有的事物都是对象&#xff0c;例如字符串、数值、数组、函数等。 对象是由属性和方法组成的。 属性&#xff1a;事物的特征&#xff0c;…

Fantasy Forest Environment

此包包含120多个预制件,您需要创建风格化的森林环境:从树木、灌木丛到岩石和蘑菇。演示场景有夏季、秋季和冬季变体! 下载:​​Unity资源商店链接资源下载链接 效果图:

Java八股文(JVM)

Java八股文のJVM JVM JVM 什么是Java虚拟机&#xff08;JVM&#xff09;&#xff1f; Java虚拟机是一个运行Java字节码的虚拟机。 它负责将Java程序翻译成机器代码并执行。 JVM的主要组成部分是什么&#xff1f; JVM包括以下组件&#xff1a; ● 类加载器&#xff08;ClassLoa…

Linux应用实战之网络服务器(三)CSS介绍

0、前言 准备做一个Linux网络服务器应用实战&#xff0c;通过网页和运行在Linux下的服务器程序通信&#xff0c;这是第三篇&#xff0c;介绍一下CSS&#xff0c;优化上一篇文章中制作的HTML页面。 1、CSS常用语法 CSS&#xff08;层叠样式表&#xff09;是用于描述HTML或XML…

数据库原理与应用(SQL Server)笔记 关系数据库

目录 一、关系数据库的基本概念&#xff08;一&#xff09;关系数据库的定义&#xff08;二&#xff09;基本表、视图&#xff08;三&#xff09;元组、属性、域&#xff08;四&#xff09;候选码、主码、外码 二、关系模型三、关系的完整性&#xff08;一&#xff09;实体完整…

Android Studio控制台输出中文乱码问题

控制台乱码现象 安卓在调试阶段&#xff0c;需要查看app运行时的输出信息、出错提示信息。 乱码&#xff0c;会极大的阻碍开发者前进的信心&#xff0c;不能及时的根据提示信息定位问题&#xff0c;因此我们需要查看没有乱码的打印信息。 解决步骤&#xff1a; step1: 找到st…

阿里通义千问Qwen1.5开源MoE模型

介绍 2024年3月28日&#xff0c;阿里团队推出了Qwen系列的首个MoE模型&#xff0c;Qwen1.5-MoE-A2.7B。它仅拥有27亿个激活参数&#xff0c;但其性能却能与当前最先进的70亿参数模型&#xff0c;如Mistral 7B和Qwen1.5-7B相媲美。相较于包含65亿个Non-Embedding参数的Qwen1.5-…

电脑关机速度很慢怎么解决?

给电脑关机&#xff0c;总是要很久才完全关闭。这是因为计算机运行了太长时间&#xff0c;并且打开的程序太多&#xff0c;则关闭时间超过十秒钟&#xff0c;这是正常的现象。还有就是计算机升级或补丁程序更新也将导致计算机缓慢关闭。此时&#xff0c;建议耐心等待关闭完成。…

SCI论文改写、防查重神器QuillBot如何付费高级版本?

写论文时候的修改软件QuillBot&#xff0c;正常的文献里的句子帖进去&#xff0c;直接给各种倒装和各种同义词替换至少10次&#xff0c;保证查不出来是别人的句子。 QuillBot是一个帮助改写内容的转述工具。 Quillbot让你的内容重组变得简单。 转述是指你用不同的词来表达&a…

深度学习每周学习总结P3(天气识别)

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制 数据链接 提取码&#xff1a;o3ix 目录 0. 总结1. 数据导入部分数据导入部分代码详解&#xff1a;a. 数据读取部分a.1 提问&#xff1a;关…

Nginx【概述:网页服务器 并发能力强】【常见命令】【部署实战】【反向代理】

Nginx-概述 介绍下载和安装下载安装重点目录和文件如下 Nginx-命令常用命令1). 查看版本2). 检查配置文件3). 启动4). 停止5). 重新加载 环境变量配置 Nginx-应用配置文件结构部署静态资源介绍测试1). 将静态资源上传到 /usr/local/nginx/html 目录2). 启动nginx3). 访问4). 配…

Linux命令及中间件安装

一.Linux简介 1.Linux操作系统概述 Linux是基于Unix的开源免费的操作系统&#xff0c;由于系统的稳定性和安全性几乎成为程序代码运行的最佳系统环境。Linux是由Linus Torvalds&#xff08;林纳斯托瓦兹&#xff09;起初开发的&#xff0c;由于源代码的开放性&#xff0c;现在…