[ Linux ] 进程优先级 和 环境变量

在上篇文章我们了解了进程的状态及Linux系统的进程状态,本篇我们主要了解进程优先级及环境变量。

1.进程优先级

说到优先级,我们首先要清楚什么是优先级,和权限有什么关系呢?

优先级是进程获取资源的先后顺序 ,而权限呢?谈的是能不能,比如:您是一名学生,您要去教室食堂吃饭,此时你是不能去的,因为你没有权限。 而优先级指的是您去学生食堂吃饭,但是可能人多,你需要排队,主要指的是先手顺序,但是一定能吃到饭。

为什么会存在优先级呢?

为什么您在食堂中吃饭需要排队呢?最主要的原因是因为资源不够,系统也是这样的。系统里面永远都是进程占大多数,而资源是少数!因此进程竞争资源是常态!存在竞争一定要确认先后,因此一定会存在优先级。

Linux下优先级的相关概念和操作

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

我们首先模拟一段简单的c语言代码

#include <stdio.h>#include <unistd.h>int main(){ while(1) { printf(“hello PRI\n”); sleep(1); } return 0;}

我们使用指令查看当前进程的优先级

ps -la

在Linux进程优先级中由两部分组成:priority(PRI) + nice(NI)

默认的优先级是80,数字越小表示优先级越高,数字越大表示优先级越低

1.2 Linux 进程优先级的更改

要更改进程优先级,需要更改的不是pri,而是NI

PRI and NIPRI也还是比较好理解的,即进程的优先级,或者通俗点说就是程序被CPU执行的先后顺序,此值越小进程的优先级别越高。那NI呢?就是我们所要说的nice值了,其表示进程可被执行的优先级的修正数值。用top命令更改已存在进程的nice:

进入top后按“r”–>输入进程PID–>输入nice值

我们使用top指令,再按r,此时系统就会提示让我们输入 PID ,输入我们要renice的PID,因此我们输入要修改的进程的PID

此时输入pid后显示让我们输入新的nice的value,这里我们首先输入-100

这里提示我们没有权限,这是因为一个进程的优先级不能轻易修改,我们想要修改要使用root用户进行修改,我们切到root用户下完成以上操作。

当我们完成以上操作后我们ctrl + C 退出top后,再次查看进程信息能够发现此时test的pri已经变成了60,而NI值是-20。可是不对呀,我们起始PRI为80,设置的NI为-100,不应该PRI成-20吗?哈哈哈,问出这个问题的同学可以自己想想,我们说进程PRI数字越小进程优先级越高,那你再小能小于0吗,小于0难道让操作系统还要倒贴你。因此操作系统规定NI的取值范围为[-20,19]。比如我们再次使用top,此时renice输入100,验证一下取值范围

ps -al

当我们输入100后,我们再次查看进程信息发现,NI的最大值确实为19,而且有一个现象是,PRI变成了99,而不是79。大家会疑惑,第一次我们renice -100时,PRI已经为60了,这里再加19不应该是79吗,为什么是99。这是现象说明了每次PRI值都会恢复为80。最终的PRI都是在80的基础上加上NI值。因此这里会显示99。

总结:PRI值越小越快被执行,那么加入nice值后,将会使得PRI变为:PRI(new)=PRI(old)+nice 。这样,当nice值为负值的时候,那么该程序将会优先级值将变小,即其优先级会变高,则其越快被执行 。所以,调整进程优先级,在Linux下,就是调整进程nice值 。nice其取值范围是-20至19,一共40个级别。需要强调一点的是,进程的nice值不是进程的优先级,他们不是一个概念,但是进程nice值会影响到进程的优先级变化。 可以理解nice值是进程优先级的修正修正数据。1.3 竞争 独立 并行 并发竞争性: 系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级 独立性: 多进程运行,需要独享各种资源,多进程运行期间互不干扰 并行: 多个进程在多个CPU下分别,同时进行运行,这称之为并行 并发: 多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发2.环境变量2.1 基本概念环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数。如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在那里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性。2.2 环境变量的引入

首先我们继续使用刚才的c语言程序,现在有一个问题,我们为什么每次执行代码的时候,都要带上./ 为什么不能像基本指令一样直接执行呢?直接执行可执行程序会爆出命令找不到。而这就跟环境变量有关。系统中是存在相关的环境变量的,保存了程序的程序的搜索路径。

Linux查看环境变量的方式是输入指令

env

而win中也是存在环境变量的,在高级系统设置中我们就可以查看环境变量,如果配置过java环境的同学一定不陌生。

而这里我们自己写的程序,为什么就找不到呢?

这是因为系统中搜索可执行程序的环境变量叫做PATH.

我们来查看一下PATH(每个人的PATH都可能不同)

env | grep PATH

我们想要显示PATH的内容使用如下指令

echo $PATH

这里环境变量PATH里面会承载多个路径,中间用 :作为分隔符,比如我们输入基本指令,系统会从PATH环境变量中一个路径一个路径进行查找,直到找到该指令或者不存在,此路径就作为改指令的搜索路径。其中ls等进本指令都在/usr/bin 路径下,而我们的myproc不在该路径下,因此当我们输入myproc的时候系统会提示找不到该指令

2.3 环境变量的修改

如果我们就要输入myproc时运行该程序,我们有3中方法。

2.3.1 把可执行程序拷入系统路径中

我们要拷贝到系统路径要是用root权限,假设我们要将myproc拷入/usr/bin路径下

sudo cp myproc /usr/bin/ls /usr/bin/myproc

此时我们直接输入myproc,,就可以达到我们的目的

但是我们不建议做,因为会污染Linux命令池

删除 之后,我们此时再运行发现查找不到了

sudo rm /usr/bin/myproc

2.3.2 把当前所处的路径添加到环境变量

我们在进行这个操作前我们介绍一下我们在Linux命令行中定义的变量,可以定义本地变量,但是他并不会以环境变量的形式存在。

aaaa=123echo $aaaa

env | grep aaaa

如果想让这个变量定义为环境变量我们要这样写,export叫做导出环境变量

export bbbb=123456env | grep bbbb

总结:

我们在命令行中定义的变量,第一种叫做普通变量。第二种叫做环境变量,环境变量具有全局属性。

此时我们会导环境环境变量了,我们将我们当前路径导入到环境变量中

pwd 查看当前环境变量export PATH=$PATH:/home/Lxy/code/linux-code/9-28

此时添加完之后,我们发现PATH路径添加了我们的myproc这条路径,之后我们输入myproc就可以直接运行程序了

3.常见环境变量

接下来我们将着重介绍了解一下env下的环境变量

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

history

我们发现最大指令3000条

user

其他内容

4.环境变量的获取

这里我们将介绍通过代码获取环境变量

4.1命令行的第三个参数

首先,大家知道main函数中有参数吗,有几个参数?

答案是有,有3个参数。

首先我们先介绍main函数中的前两个参数,第一个参数是 argc 表示argv数组的个数。第二个参数是一个指针数组,这个数组里面放的什么呢?我们首先来看看结果[for循环初始化声明仅在c99下允许 因此编译时带上 -std=c99]

#include <stdio.h>#include <unistd.h>int main(int argc,char* argv[]){ //char* argv[]:什么类型?里面放什么呢? for(int i = 0; i < argc , ++i) { printf(“argv[%d]:%s\n”,i,argv[i]); } //printf(“hello\n”); return 0;}

当我们进行命令行输入时,./myproc叫做可执行程序 -a -b -c -d等等这些叫做选项。这些都是字符串,都存在argv这个指针数组中。我们给main函数传递的argc,char* argv[],命令行参数传递的是命令行中输入的程序名和选项!!那意义是什么呢?

我们知道了这两个参数 我们可以写一个最简单的计算器程序

#include <stdio.h>#include <unistd.h>#include <string.h>// -a 加法// -s 减法int main(int argc,char *argv[]){ if(argc != 4) { printf(“Usage: %s [-a|-s|-m|-d] one_data two_data\n”, argv[0]); return 0; } int x = atoi(argv[2]); int y = atoi(argv[3]); if(strcmp(“-a”, argv[1]) ==0) { printf(“%d+%d=%d\n”,x, y, x + y); } else if(strcmp(“-s”, argv[1]) ==0) { printf(“%d-%d=%d\n”,x, y, x – y); } else if(strcmp(“-m”, argv[1]) ==0) { printf(“%d*%d=%d\n”,x, y, x * y); } else if(strcmp(“-d”, argv[1]) ==0 && y != 0) { printf(“%d/%d=%d\n”,x, y, x / y); } else { printf(“Usage: %s [-a|-s|-m|-d] one_data two_data\n”, argv[0]); } return 0;}

意义:

因此,这两个参数最大的意义是同一个程序,通过传递不同的参数,让同一个程序有不同的执行逻辑,执行结果。这也是我们平时使用的 ls -a ls -l ,这就是Linux系统中会根据不同的选项,让不同的命令,有不同的表现,指令中那么多选项的由来和起作用的方式。

在win系统的也是存在这样的 cmd

main的第三个参数

man函数是可以带第三个参数的!这第三个参数正是环境变量

int main(int argc,char *argv[],char *env[]){ for(int i = 0;env[i];i++) { printf(“env[%d]:%s\n”,i,env[i]); } return 0;}

程序输出结果

env查看环境变量

结论:一个进程会被传入环境变量参数的!!

4.2 通过第三方变量environ获取

我们也可以使用第三方变量environ获取

我们可以通过man手册查看一下environ,是C语言给我提供的一个全局变量。

libc中定义的全局变量environ指向环境变量表,environ没有包含在任何头文件中,所以在使用时 要用extern声明。

#include <stdio.h>#include <unistd.h>#include <string.h>#include <stdlib.h>int main(int argc,char *argv[]){ extern char ** environ; int i = 0; for(;environ[i];i++) { printf(“%s\n”,environ[i]); }

4.3 通过系统调用获取或设置环境变量getenvputenv#include <stdio.h>#include <stdlib.h>int main(int argc,char *argv[]){ printf(“%s\n”,getenv(“PATH”)); return 0;}

(本篇完)

年岁有加,并非垂老,理想丢弃,方堕暮年。

[ Linux ] 进程优先级 和 环境变量

相关文章:

你感兴趣的文章:

标签云: