Linux_进程的优先级环境变量上下文切换

文章目录

    • 一、进程的优先级
    • 二、进程的四个重要概念
    • 三、上下文切换
    • 四、环境变量
      • 4.1 查看当前shell环境下的环境变量与内容

一、进程的优先级

  • 什么是优先级?

    • 指定一个进程获取某种资源的先后顺序
    • 本质是进程获取cpu资源的优先顺序
  • 为什么要有优先级

    • 进程访问的资源(CPU)是有限的

操作系统关于调度和优先级的原则:分时操作系统,基本的公平,如果进程因为长时间不被调整,就造成了饥饿问题

  • Linux的优先级特点以及查看方式

  • 查看进程的优先级
ps -lA

在这里插入图片描述

  • PRI:进程优先级
  • NI:进程优先级的修正数据

  • 其中PRI值越低优先级越高

  • 因为PRI值是由操作系统内核动态调整的,我们无法直接去调整这个值,所以我们必须通过nice值去调整它。nice值就是上图PRI后面NI。

  • 因为PRI是系统内核去动态调整的,我们修改后需要经过内核的允许,如果这个PRI值超过了内核的最大限度,那么这个值就会保留在临界值

  • 我们的计算公式为:新的PRI = 进程默认PRI + nice值,这个nice值有正负数,我们可以举一个例子:一个进程的PRI为80,我们给NI值为-10,再根据上面的公式得出新的PRI为70


  • 那么如何修改呢?我们可以写一个代码来看一下:
#include<stdio.h>
int main()
{while(1){}return 0;
}
  • 我们可以查看它的PRI和NI值

在这里插入图片描述

  • 我们可以通过下面的命令进行修改

  • number为想要的nice值,PID为要操作的进程

renice [number] [PID]               
  • 首先查看一下该进程的id

在这里插入图片描述

  • 然后进行修改~

在这里插入图片描述

  • 修改后就变成了PRI是70,NI是-10

在这里插入图片描述

二、进程的四个重要概念

  • 竞争性:因为cpu资源优先,所以进程难免会存在竞争行为,具体体现在优先级上。
  • 独立性:进程运行期间,各个进程是不会相互干扰的,即使是父子进程。
  • 并行:当有多个cpu时,这些cpu同时处理多个进程的行为叫做并行。
  • 并发:在一段时间内,每个进程都可以被cpu处理一部分指令,这种行为称为并发。

假设cpu处理一个进程的时间为1秒,那么1个cpu处理99个进程的时间就是99秒。但是当有一台拥有3个cpu的计算机处理这99个进程时,只需要33秒。这就是并行,多个cpu同时处理多个进程。

三、上下文切换

  • 每个任务运行前,CPU 都需要知道任务从哪里加载、又从哪里开始运行,这就涉及到 CPU 寄存器 和 程序计数器(PC):

如何切换?

  • 将前一个 CPU 的上下文(也就是 CPU 寄存器和程序计数器里边的内容)保存起来;
  • 然后加载新任务的上下文到寄存器和程序计数器;
  • 最后跳转到程序计数器所指的新位置,运行新任务。

被保存起来的上下文会存储到系统内核中,等待任务重新调度执行时再次加载进来。

CPU 的上下文切换分三种:进程上下文切换、线程上下文切换、中断上下文切换。

  • 把临时数据转存到操作系统的行为叫做上下文保护,把临时数据写回寄存器内的行为叫做上下文恢复。

四、环境变量

  • 我们对于Linux的理解,指令就是程序,我们写的C语言代码也是一个程序,那么有一个问题,为什么Linux的指令他直接就可以在bash(终端)上运行,为什么我们写的代码生成的可执行文件

在这里插入图片描述

  • 在我们运行程序的时候,需要知道此程序在哪个位置

  • 在Linux的中的命令,它为什么不需要指定路径来执行呢?是因为有个叫【PATH】的环境变量,在我们输入指令后,会在指定路径下查找,如果找不到要执行的指令就会返回错误【command not found】

在这里插入图片描述

  • 因为【PATH】变量没有记录我们输入的指令的位置信息,所以我们必须手动指定指令的位置。那么我们可以总结出指令(程序)是如何执行的

  • 我们可以查看一下PATH下有哪些路径
echo $PATH

在这里插入图片描述

  • 可以看到上面是有各种路径每个路径是一下【:】分割,我们可以看到有一个/usr/bin目录,那么我们写的这个程序也就可以拷贝到这个目录下就可以不指定路径直接执行了
  • 第二个方法是将我当前这个目录的路径添加到这个环境变量中,这样也可以

  • 我们可以用下面的这条指令来修改系统变量
export PATH=路径

在这里插入图片描述

  • 发现我们刚刚查看的变量不在了,ls也无法执行了

在这里插入图片描述

  • 这个时候不要慌,我们可以另外再开一个终端再看

在这里插入图片描述

  • 那么我们如何正确的向[PATH]添加一个路径呢?我们用到下面的指令:
export PATH=$PATH:路径
  • 这就完成了添加一个环境变量的操作

在这里插入图片描述

  • 那么为什么新开了一个终端它就又恢复了呢?

    • 这是因为在我们默认查看的环境变量是内存级
    • 最开始的环境变量不是在内存中,是在对应的配置文件中,登录Linux系统的时候它会首先加载到bash进程中(内存)
  • 那么这个配置文件在哪?

.bash_profile # 当前登录用户环境变量
.bashrc       # 当前登录用户环境变量
/etc/bashrc   # 全局环境变量

4.1 查看当前shell环境下的环境变量与内容

env

在这里插入图片描述

  • 环境变量是随着启动操作系统时生成的,也就是说,环境变量是属于bash的。

  • 指令是一个程序,在bash上执行,那么这个程序就是bash的子进程

  • 我们平时所用的pwd命令就是有一个环境变量叫pwd,这个环境变量存储着用户当前的所在位置

在这里插入图片描述


  • 我们也可以自己实现一个pwd指令

  • 在实现的时候需要了解一个函数getenv,我们用man手册查看一下

在这里插入图片描述

#include<stdio.h>
#include<stdlib.h>
int main()
{char* ret = getenv("PWD");printf("%s\n",ret);return 0;
}
  • 可以看到我们就实现了这个

在这里插入图片描述

  • 我们在bash上运行的程序,是bash的子进程,而环境变量是属于bash的,子进程为什么能用父进程的环境变量?这是因为,子进程可以继承父进程的环境变量!并且,环境变量一定是全局属性的!

  • 在子进程是如何继承环境变量的?子进程是不是有一个主函数?这个主函数我们平时使用时是没有参数的,但实际上它是可以带参数的!还能带三个!
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char* argv[], char* environ[])
{return 0;
}
  • 第一个参数代表的意思为:指令参数的个数(包括指令);
  • 第二个参数代表的意思为:指令参数的指针数组(因为指令参数是一个字符串);
  • 第三个参数代表的意思为:环境变量的指针数组(因为环境变量是一个字符串)。我们一般不使用第三个参数,而是使用操作系统提供的外部的指针数组指针【char** environ】或者是系统提供的接口函数getenv()

  • 我们就可以实现一个带参数的指令,就像ls类似的
#include <stdio.h>
#include <string.h>
int main(int argc,char* argv[])
{if(argc < 2){printf("指令参数太少!\n");return 1;}if(strcmp(argv[1],"-a")==0){printf("执行-a\n");}else if(strcmp(argv[1],"-b")==0){printf("执行-b\n");}else{printf("指令有误!\n");                                                                                                                                                        }return 0;
}

在这里插入图片描述

  • 我们可以再写一个代码来验证一下
#include <stdio.h>
#include <string.h>
int main(int argc,char* argv[])
{printf("%d\n",argc);int i=0;                                                                                                                                                                           for(i=0;i<argc;i++){printf("%s\n",argv[i]);}return 0;
}

在这里插入图片描述

  • 从上面 可以看出 [argc]是存储指令参数的个数的(包括指令),[char* argv[]]这个指针数组是存储指令参数的(包括指令)

  • 对于第三个参数,是一个指针数组,存储的是各个环境变量的内容,因为这些内容是字符串常量,而表示字符串常量通常使用其首字符地址

  • 我们是很少使用第三个参数的,因为这个数组存储了所有的环境变量,想要找到特定的环境变量还是挺困难的,那么我们使用这段代码,证明第三个参数存储了环境变量:

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

在这里插入图片描述

  • 或者使用另一种写法可以完成
#include <stdio.h>
#include <string.h>
int main(int argc,char* argv[])
{extern char** environ;int i=0;                                                                                                                                                                         for( i=0;environ[i];i++){printf("[%d]-->%s\n",i,environ[i]);}return 0;
}

在这里插入图片描述

  • 环境变量是具有全局属性的,也就意味着子进程只能继承父进程的具有全局属性的环境变量。称作本地变量。如何设置本地变量呢?我们只需要在bash上面按这个格式敲指令:

  • 变量中间不能有空格

[变量名]=[内容]       

在这里插入图片描述

  • 我们发现使用env来查看我们设置的变量,并不能显示出结果,证明了我们刚刚设置的变量是本地变量

  • 但是使用【echo】命令还可以查看到,因为echo是可以操作环境变量的,所用echo命令是可以操作所有的变量的,不管是本地变量还是环境变量。

  • 子进程并没有继承父进程的本地变量,那我们如何使本地变量变成环境变量呢?我们输入下面这个指令:

export [变量名称]     

在这里插入图片描述

  • 现在我们学会了如何设置本地变量和如何把本地变量转换成环境变量了。那么如何查看本地变量呢,或者说如何查看所有的变量呢?我们使用下面这条命令:
set

在这里插入图片描述

  • 取消变量可以使用下面这条命令
unset [变量名]

在这里插入图片描述

最后,本文学习了Linux_进程的优先级&&环境变量&&上下文切换,感谢收看

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Entity Framework】EF日志-简单日志记录

【Entity Framework】EF日志-简单日志记录 文章目录 【Entity Framework】EF日志-简单日志记录一、概述二、EF日志分类三、简单的日志记录3.1 配置3.2 日志记录到控制台3.3 记录到凋试窗口3.4 记录到文件3.5 敏感数据处理3.6 详细查询异常3.6 日志级别3.7 消息内容和格式设置 一…

基于Scala开发Spark ML的ALS推荐模型实战

推荐系统&#xff0c;广泛应用到电商&#xff0c;营销行业。本文通过Scala&#xff0c;开发Spark ML的ALS算法训练推荐模型&#xff0c;用于电影评分预测推荐。 算法简介 ALS算法是Spark ML中实现协同过滤的矩阵分解方法。 ALS&#xff0c;即交替最小二乘法&#xff08;Alte…

Java SpringBoot中优雅地判断一个对象是否为空

在Java中&#xff0c;可以使用以下方法优雅地判断一个对象是否为空&#xff1a; 使用Objects.isNull()方法判断对象是否为空&#xff1a; import java.util.Objects;if (Objects.isNull(obj)) {// obj为空的处理逻辑 }使用Optional类优雅地处理可能为空的对象&#xff1a; impo…

Centos8/linux/虚拟机安装docker

docker分为ce版和ee版&#xff0c;个人使用ce版就行了&#xff0c;别问为什么&#xff0c;问就是ee版收费。 这是在线版的&#xff0c;离线版的请参考Centos8离线下载安装docker 1.首先切换到root用户 2.为确保安装时出现不必要的问题&#xff0c;先更新一下yum包 sudo yum…

Mac上Matlab_R2023b ARM 版 启动闪退(意外退出)解决方法

安装好后&#xff0c;使用 "libmwlmgrimpl.dylib" 文件替换掉"/Applications/Matlab_R2023b.app/bin/maca64/matlab_startup_plugins/lmgrimpl"文件夹下的同名文件 在终端下执行如下命令&#xff1a; codesign --verbose --force --deep -s - /Applicat…

大数据学习第十二天(hadoop概念)

1、服务器之间数据文件传递 1&#xff09;服务器之间传递数据&#xff0c;依赖ssh协议 2&#xff09;http协议是web网站之间的通讯协议&#xff0c;用户可已通过http网址访问到对应网站数据 3&#xff09;ssh协议是服务器之间&#xff0c;或windos和服务器之间传递的数据的协议…

golang和Java的简单介绍和对比

一、golang 1、Golang简介 Golang&#xff0c;也称为Go&#xff0c;是由Google公司在2009年推出的开源编程语言&#xff0c;由罗伯特格瑞史莫(Rob Pike)、肯汤普逊(Ken Thompson)、罗勃派克(Robert Griesemer)等人设计。Go语言的目标是在保持简单高效的编程模型的同时&#xf…

Linux系统----------探索mysql数据库MHA高可用

目录 一、MHA概述 1.1 什么是 MHA 1.2MHA 的组成 1.2.1MHA Node&#xff08;数据节点&#xff09; 1.2.2MHA Manager&#xff08;管理节点&#xff09; 1.3MHA 的特点 1.4MHA工作原理 1.5数据同步的方式 1.5.1同步复制 1.5.2异步复制 1.5.3半同步复制 二、搭建 MySQ…

ios 之 netty版本swiftNio(TLSHandler 创建)

SwiftNio 简介 用于高性能协议服务器和客户端的事件驱动、无阻塞的网络应用程序框架。 SwiftNIO是一个跨平台异步事件驱动的网络应用程序框架&#xff0c;用于快速开发可维护的高性能协议服务器和客户端。 这就像Netty&#xff0c;但是为Swift写的。 Xcode引入swiftNio 在实…

蓝桥杯第八届c++大学B组详解

目录 1.购物单 2.等差素数列 3.承压计算 4.方格分割 5.日期问题 6.包子凑数 7.全球变暖 8.k倍区间 1.购物单 题目解析&#xff1a;就是将折扣字符串转化为数字&#xff0c;进行相加求和。 #include<iostream> #include<string> #include<cmath> usin…

git源码泄露

Git 源码泄露 开发人员会使用 git 进行版本控制&#xff0c;对站点自动部署。但如果配置不当&#xff0c;可能会将 .git 文件夹直接部署到线上环境&#xff0c;这就引起了 git 泄露漏洞&#xff0c;我们可以利用这个漏洞直接获得网页源码。 确定是否存在泄漏 &#xff08;1&…

自动驾驶的世界模型:综述

自动驾驶的世界模型&#xff1a;综述 附赠自动驾驶学习资料和量产经验&#xff1a;链接 24年3月澳门大学和夏威夷大学的论文“World Models for Autonomous Driving: An Initial Survey”。 在快速发展的自动驾驶领域&#xff0c;准确预测未来事件并评估其影响的能力对安全性…

视频汇聚/安防监控/视频存储EasyCVR平台EasyPlayer播放器更新:新增【性能面板】

视频汇聚/安防监控/视频存储平台EasyCVR基于云边端架构&#xff0c;可以在复杂的网络环境中快速、灵活部署&#xff0c;平台视频能力丰富&#xff0c;可以提供实时远程视频监控、视频录像、录像回放与存储、告警、语音对讲、云台控制、平台级联、磁盘阵列存储、视频集中存储、云…

从零开始,构建智慧企业:人事管理软件新升级全攻略

本文从智能化人事管理的六大核心要素探讨如何打造一个适应现代企业需求的智能化人事管理系统&#xff0c;并介绍几款市场上表现优秀的人事管理软件。 随着我国经济的发展&#xff0c;企业全球化是大势所趋&#xff0c;难免会出现跨国员工数量增加、办公地点分散、跨部门协作等…

重学SpringBoot3-SpringBoot可执行JAR的原因

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 重学SpringBoot3-SpringBoot可执行JAR的原因 Spring Boot可执行JAR的结构打包运行JAR 包内部结构 工作原理优点总结 Spring Boot 的一个核心特性是它的可执行 JAR&#x…

Canvas实现数字电子时钟(带粒子掉落效果)

前置知识 Canvas实现简易数字电子时钟 效果 逻辑代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>粒子时钟</title><style>body {margin: 0;overflow: hidden}</style> </…

Redis开源协议调整,我们怎么办?

2024年3月20日, Redis官方宣布&#xff0c;从 Redis 7.4版本开始&#xff0c;Redis将获得源可用许可证 ( RSALv2 ) 和服务器端公共许可证 ( SSPLv1 ) 的双重许可&#xff0c;时间点恰逢刚刚完成最新一轮融资&#xff0c;宣布的时机耐人寻味。 Redis协议调整&#xff0c;对云计算…

Nginx三大常用功能“反向代理,负载均衡,动静分离”

注意&#xff1a;以下案例在Windows系统计算机作为宿主机&#xff0c;Linux CentOS 作为虚拟机的环境中实现 一&#xff0c;Nginx配置实例-反向代理 1.反向代理 案例一 实现效果&#xff1a;使用nginx反向代理&#xff0c;访问 www.123.com 直接跳转到127.0.0.1:8080 准备工…

Golang Context是什么

一、这篇文章我们简要讨论Golang的Context有什么用 1、首先说一下Context的基本作用&#xff0c;然后在讨论他的实现 (1)数据传递&#xff0c;子Context只能看到自己的和父Context的数据&#xff0c;子Context是不能看到孙Context添加的数据。 (2)父子协程的协同&#xff0c;比…

vue两个特性和什么是MVVM

一、什么是vue 1.构建用户界面 用vue往html页面中填充数据&#xff0c;非常的方便 2.框架 框架是一套线成的解决方案 vue的指令、组件&#xff08;是对ui结构的复用&#xff09;、路由、vuex 二、vue的特性 1.数据驱动视图 2.双向数据绑定 1.数据驱动视图 数据的变化会驱动…