[Linux]进程优先级 & Linux中的环境变量

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

🥁作者 华丞臧.
📕​​​​专栏【LINUX】
各位读者老爷如果觉得博主写的不错请诸位多多支持(点赞+收藏+关注)。如果有错误的地方欢迎在评论区指出。
推荐一款刷题网站 👉 LeetCode刷题网站


文章目录


前言

操作系统具有进程管理的功能可以同时管理多个进程但是系统里永远都是进程占大多数而资源是少数那么当多个进程同时响应时操作系统该如何选择呢因此进程之间需要区分优先级同时操作系统也是一款软件一个进程那么在操作系统的源代码中一定存在一些参数用来指定操作系统的运行环境而这些参数被称为环境变量。

一、Linux中进程优先级

1.1 基本概念

优先级是进程获取资源的先后顺序。

  • 本质是资源不足CPU资源分配的先后顺序就是指进程的优先权
  • 优先权高的进程有优先执行权配置进程优先权对多任务环境的Linux很有用可以改善系统性能
  • 优先级还可以把进程运行到指定的CPU上这样一来把不重要的进程安排到某个CPU可以大大改善系统整体性能。

1.2 查看系统进程

在Linux系统中用以下命令会输出一下几个内容

  • ps -l显示当前终端下的进程信息
    在这里插入图片描述
    其中重要信息如下
  • UID代表执行者的身份
  • PID代表这个进程的代号
  • PPID父进程代号代表这个进程是由哪个进程发展衍生而来的
  • PRI代表这个进程可被执行的优先级其值越小越早被执行
  • NI代表这个进程nice值。
  • ps -la
    在这里插入图片描述

PRI && NI

  • PRI也还是比较好理解的即进程的优先级或者通俗点说就是进程被CPU执行的先后顺序这个值越小进程优先级越高
  • NI也就是nice值相当于副优先级其表示进程可被执行的优先级的修正数值
  • PRI值越小越快被执行那么加入nice值后将会使得PRI变为PRI(new) = PRI(old) + nice
  • 当nice值为负值时该进程优先级值将会变小其优先级会变高进程越快被执行
  • nice取值范围在-20~19一共40个级别。

PRI vs NI

  • 需要强调一点的是进程的nice值不是进程的优先级他们不是一个概念但是进程nice值会影响到进程的优先级变化
  • 可以理解nice值是进程优先级的修正修正数据

1.3 查看进程优先级的命令

  • top普通用户必须要提权成为超级用户才能使用top修改进程NI优先级并且其范围在-20~19之间
  • 进入top后按“r”–>输入进程PID–>输入nice值
  • 每次重新设置nice值的时候PRI都会重新设置为80系统默认值然后再加上nice值

在这里插入图片描述

修改之前
在这里插入图片描述

修改nice为-100发现NI的值并不是-100而是-20
在这里插入图片描述

修改nice为100发现NI的值并不是100而是19
在这里插入图片描述

为什么nice值的范围在-20~19呢?

首先Linux系统一共有140个优先级很多优先级不是给普通的进程使用的60~99这40个优先级是给用户使用的Linux系统不允许用户随意修改进程优先级因为操作系统有很多系统需要的进程他们维持着操作系统的运行如果用户能随意修改优先级就可能导致系统的进程优先级过低造成系统进程不能及时运行而使用操作系统性能降低。

1.4 其他概念

  1. 竞争性: 系统进程数目众多而CPU资源只有少量甚至1个所以进程之间是具有竞争属性的。为了高
    效完成任务更合理竞争相关资源便具有了优先级
  2. 独立性: 多进程运行需要独享各种资源多进程运行期间互不干扰进具有独立性不会因为一个进程挂掉或者异常而导致其他进程出现问题
  3. 并行: 多个进程在多个CPU下分别同时进行运行这称之为并行
  4. 并发: 多个进程在一个CPU下采用进程切换的方式在一段时间之内让多个进程都得以推进称之为并发

并行 && 并发
CPU能同时运行多个进程吗答案是不能一个CPU在同一时刻只能运行一个进程。

  • 并行就是指在多个CPU中运行多个进程一个CPU运行一个进程。
  • 并发是指在一个时间段内多个进程会通过切换交叉的方式在一个CPU上让多个进程代码在一段时间内都得到推进。

我们遇到的大部分操作系统都是分时的简单来说就是每一个进程都可以在一小段时间片中占有CPU资源每个进程的这一小段时间片形成一段时间时间片是一段非常非常小的时间段相对于CPU是慢的但对于人来说是非常非常快的。时间片的分配是操作系统中软件模块调度器分配的。

在这里插入图片描述

进程抢占操作系统不是完全根据队列来进行先后调度的如果突增优先级更高的进程调度器会将正在进行的进程从CPU上剥离下去并将优先级更高优先级的进程加载到CPU上。

补充操作系统会根据不同的优先级队列是先进先出的不能进行中间插入删除操作将特定的进程放入到不同的队列中。

进程间切换
CPU内的寄存器作用是可以临时存储数据非常少但非常重要。
CPU中寄存器分为可见寄存器和不可见寄存器当进程在被执行的过程中一定会存在大量的临时数据这些数据会暂存在CPU内的寄存器中寄存器中存放的是进程在运行中产生的上下文数据当进程被剥离时需要保存该进程的上下文数据当进程恢复的时候需要将曾经保存的上下文数据恢复到寄存器中。

上下文数据进程在运行过程中产生的各种寄存器数据我们叫做进程的硬件上下文数据。上下文数据存放在进程PCBtast_struct当中。

二、Linux中的环境变量

2.1 基本概念

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

  • 如我们在编写C/C++代码的时候在链接的时候从来不知道我们的所链接的动态静态库在哪里但 是照样可以链接成功生成可执行程序原因就是有相关环境变量帮助编译器进行查找。
  • 环境变量通常具有某些特殊用途还有在系统当中通常具有全局特性

2.2 常见环境变量

  • PATH指定命令的搜索路径
  • HOME指定用户的主工作目录
  • SHELL:当前Shell,它的值通常是/bin/bash。

Linux中的指令本质是软件即编译好的可执行程序那么我们发现我们自己编写的代码生成的可执行程序不能像Linux当中的指令那样使用而是需要加上路径才行如下图
在这里插入图片描述

Linux系统的指令可以不带路径直接使用这是得益于环境变量PATH当我们使用系统指令时操作系统会去PATH中保存的路径中查找指定的指令找到了直接使用没找到报错。

如下图找到了直接使用
在这里插入图片描述

没找到报错如下图
在这里插入图片描述

PATH中保存系统中存放指令程序文件的路径。
在这里插入图片描述

Linux中的系统指令一般存放在 /usr/bin 中如下图
在这里插入图片描述

2.3 查看环境变量

  • echo $NAMENAME指你的环境变量名称
    在这里插入图片描述
  • env显示所有的环境变量。
    在这里插入图片描述

2.4 测试环境变量

2.4.1 测试PATH

将指定程序的路径加入到PATH环境变量中去再不加路径运行指定的程序此时程序是可以运行的修改PATH指令如下

//其中$表示当前PATH中的值即PATH中保存的所有路径;
//:是路径分隔符
export PATH=$PATH:[路径]

//下面的指令也可以修改PATH只不过指定路径会覆盖PATH中保存的路径
export PATH=[指定路径]

在这里插入图片描述
注意这种修改环境变量的方式重启客户端就会刷新即恢复系统成为默认的PATH。

2.4.2 测试HOME

在这里插入图片描述

2.5 环境变量的相关命令

Linux命令行中可以定义变量

  • export

功能设置一个新的环境变量也可以在已有的环境变量中追加新的值
格式export 环境变量名=($环境变量名:)[追加值]

在这里插入图片描述

在这里插入图片描述

设置一个新的环境变量
在这里插入图片描述

  • set

功能显示本地定义的shell变量本地变量和环境变量
格式set | grep 变量名通常与grep连用。

本地变量和环境变量
命令行中可以定义变量变量分为本地变量和环境变量
在这里插入图片描述

查看本地变量
在这里插入图片描述

  • unset

功能清除环境变量
格式unset 变量名

在这里插入图片描述

2.6 环境变量的组织方式

在这里插入图片描述
每个程序都会收到一张环境表环境表是一个字符指针数组每个指针指向一个以’\0’结尾的环境字符串环境表必须以NULL结束。

2.7 获取环境变量

2.7.1 main函数参数

首先要知道main函数是可以带参数的。

//main函数可以带三个参数
//argc(argv)数组当中元素的个数
//argv[]数组当中的各种参数,必须以NULL结束
//env存放环境变量的地址
int main(int argc, char *argv[], char *env[])
{}

//例子code.c
#include <stdio.h>

int main(int argc, char *argv[])
{
  int i = 0;
  while(argv[i] != NULL)
  {
    printf("%d: %s\n", i, argv[i]);
    ++i;
  }
  //printf("%d%s\n", argc, argv[argc]);
  return 0;
}

当我们实际进行命令行输入时输入的程序名和后面的相关选项存放在main函数的参数当中也就是argv[argc]中以空格为分隔符注意argv数组必须以NULL空指针结尾
我们称传递给main函数的int argc、char *argv[]为命令行参数

命令行参数可以让我们对同一个程序通过传递不同的参数使同一个程序有不同的执行逻辑或者执行结果。

在这里插入图片描述

获取环境变量还可以通过main函数第三个参数获取代码如下

注意C语言中无参的函数可以传参数过去并且不会报错。

//env.c
#include <stdio.h>

int main(int argc, char *argv[], char *env[])
{
    (void)argc;  //去除警告代码中没有使用该变量会有警告
    (void)argv;
 	int i = 0;
 	for(; env[i]; i++)
 	{
 		printf("%s\n", env[i]);
 	}
 	return 0;
}

可以看到程序成功获取到了环境变量那么这些变量为什么可以获取到呢

结论命令行中运行的进程都是bash的子进程而环境变量是具有全局属性因此bash中的环境变量会被子进程继承所以命令行上运行的进程可以获取环境变量。

在这里插入图片描述

2.7.2 第三方变量environ获取环境变量

C语言会给我们定义了一个全局的第三方变量environ可以environ中获取所有的环境变量

#include <stdio.h>

int main(int argc, char *argv[])
{
 	extern char **environ;
 	
 	int i = 0;
 	for(; environ[i]; i++)
 	{
 		printf("%s\n", environ[i]);
 	}
 	
 	return 0;
}

在这里插入图片描述

2.7.3 系统调用获取或设置环境变量

getenv系统调用接口可以通过指定的环境变量名获取指定的环境变量。
在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>

int main()
{
    const char *usr = getenv("USER"); //获取当前用户名
    printf("%s\n", usr);
    return 0;
}

在这里插入图片描述

2.8 环境变量和本地变量

  • 环境变量通常是具有全局属性的可以被子进程继承下去。
  • 环境变量的最大意义标识当前使用的Linux用户。
  • 所谓的本地变量本质就是在bash内部定义的变量不会被子进程继承下去。
//code2.c
#include <stdio.h>
#include <stdlib.h>

int main()
{
    char * env = getenv("MYENV");
    
    if(env)
    {
        printf("%s\n", env);
    }

    return 0;
}

通过上面程序的运行结果可以很好的说明环境变量具有全局性可以被子进程继承而本地变量不能被子进程继承。
在这里插入图片描述

需要注意Linux下大部分命令是通过子进程的方式执行的但是还有一部分命令不通过子进程的方式执行而是由bash自己执行调用自己对应的函数来完成特定的功能我们把这种命令称为内建命令。
如下图echo和cd就是内建命令。
cd ..应该改变子进程的工作目录但实际上cd改变的是bash父进程的工作目录。
在这里插入图片描述

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: linux