进程优先级 环境变量
进程优先级
基本概念
- cpu资源分配的先后顺序,就是指进程的优先权(priority)。
- 优先权高的进程有优先执行权利。配置进程优先权对多任务环境的linux很有用,可以改善系统性能。
- 还可以把进程运行到指定的CPU上,这样一来,把不重要的进程安排到某个CPU,可以大大改善系统整体性能
注:因为CPU的资源是有限的,所以使用进程优先即做为一个分配资源的依据,更好地利用CPU资源
查看进程优先级
指令
ps -l
UID : 代表执行者的身份
PID : 代表这个进程的代号
PPID* :代表这个进程是由哪个进程发展衍生而来的,亦即父进程的代号
PRI :代表这个进程可被执行的优先级,其值越小越早被执行
NI :代表这个进程的nice值
PRI and NI
PRI也还是比较好理解的,即进程的优先级,或者通俗点说就是程序被CPU执行的先后顺序,此值越小进程的优先级别越高
NI就是我们所要说的nice值了,其表示进程可被执行的优先级的修正数值
PRI值越小越快被执行,那么加入nice值后,将会使得PRI变为:PRI(new)=PRI(old)+nice
这样,当nice值为负值的时候,那么该程序将会优先级值将变小,即其优先级会变高,则其越快被执行所以,调整进程优先级,在Linux下,就是调整进程nice值
nice其取值范围是**-20至19**,一共40个级别
理解nice的取值范围为什么是40
- 实际上我们修改进程优先级只能是局部修改
- 一般进程优先级高的一般是系统内部的进程,而如果我们可以随意将我们自己创建出来的进程的优先级设置先于系统的进程,我们的进程可能就会霸占原来属于系统进程的资源,这时候就容易会造成**“进程饥饿”**问题
- 另进程优先级是配合os的调度器使用的,调度器的作用就是使每个进程都能均匀得享受CPU资源,而如果我们可以随便修改进程的优先级,就会对os调度器的工作造成干扰
PRI vs NI
- 需要强调一点的是,进程的nice值不是进程的优先级,他们不是一个概念,但是进程nice值会影响到进程的优先级变化。可以理解nice值是进程优先级的修正数据
修改进程优先级的方法
top r
指令:
top r 进程pid 设置nice值
演示:
输入top,就会显示这样的界面
而后我们输入r,就会让我们输入需要修改nice值的进程pid
回车之后,就可以设置我们所需要设置的nice,图中设置为100
运行结果:
结果最后的nice值是19,并不是100,也就是如果我们设置的nice值超过【-20,19】,他会自动缩减
注:
- PRI的值并不会因为我们修改的次数而叠加,默认初始值都是80,也就是无论我们修改多少次 最终的PRI值都等于=80+nice,针对普通进程
- 一般都不建议我们自己去尝试修改nice值,因为我们并不懂进程优先级,而最懂它的还是我们的os,我们学习阶段只需要使用top r 查看一下效果即可
其他概念
- 竞争性: 系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级
- 独立性: 多进程运行,需要独享各种资源,多进程运行期间互不干扰
- 并行: 多个进程在多个CPU下分别,同时进行运行,这称之为并行
- 并发: 多个进程在一个CPU下采用进程切换的方式(通过时间片),在一段时间之内,让多个进程都得以推进,称之为并发
环境变量
基本概念
- 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数
如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。
- 环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性(后面会解释)
常见环境变量
- PATH : 指定命令的搜索路径
- HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
- SHELL : 当前Shell,它的值通常是/bin/bash
查看环境变量的方式: echo $
ehco $环境变量名
例:
环境变量的意义
例1:为什么我们每次登录时,我们每次都会到达该用户的工作目录下
就是因为有HOME环境变量,而我们每次登录时,os就可以根据不同用户的HOME变量,登录到不同的工作路径下
例2:为什么我们执行程序加 ./a.out
实际上:./的意义就是告诉我们所要执行的程序,在什么位置(./就是告诉搞作系统,我们要执行的文件在当前路径下的a.out文件)
思考:而为什么我们执行shell脚本 ls命令时不需要使用./
想必大家应该都很清楚了,肯定又是环境变量的功劳,因为环境变量PATH的缘故,os执行操作系统本身的代码时,会去PATH里面保存的路径下去寻找,而后执行找到的文件
查看环境变量PATH
echo $PATH
思考:我们能否将不使用./就可以运行我们自己写的程序呢?
答案是当然可以,而且方法很多,下面介绍俩种方法
1.添加当前路径到环境变量PATH里去
指令:
export PATH=$PATH:所要添加的环境变量
演示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-slFUSU9p-1682295647535)(http://rtjy7uas6.hn-bkt.clouddn.com/202304240810142.png)]
注:
- 其中我们上面添加到环境变量PATH里面的值,只在本次登录有效,后续登录就不会出现了,所以不需要我们自己进行清理工作
2.将我们的文件放到系统路径下
第二种方法就不在这显示了,实现方法也很简单,就是将指定文件拷贝或剪切到指定目录下(使用cp mv即可)
但需要注意的是:我们测试完之后,要将该文件删除掉,因为文件是不会自动删除的,不然我们以后执行系统指令时,可能会有奇怪的输出
环境变量相关命令
本地变量
与本次登录(session)有关的变量,只在本次登录内有效
echo: 显示某个环境变量值
export: 设置一个新的环境变量
env: 显示所有环境变量
unset: 清除环境变量
set: 显示本地定义的shell变量和环境变量
演示:
认识main函数中的俩个参数 argc argv
我们其中很多人都不知道main函数其实还有参数,就更别说知道main函数的参数有什么用了
而实际上main函数当中有俩个参数,分别时argc和argv
int main(int argc,char * argv[])
- argc: 记录了argv中的数据个数
- argv: 保存了命令行参数
也就是说我们实际上,可以通过上面俩个参数,获取到我们刚刚输入的命令行指令
代码:
#include <stdio.h>
#include <stdlib.h>
W>int main(int argc,char *argv[])
{
//测试命令行参数
for(int i=0;i<argc;i++)
{
printf("agrv[%d]->%s\n",i,argv[i]);
}
return 0;
}
运行结果:
使用代码获取环境变量的3种方式
前面我们讲了使用env可以查看系统里面的环境变量,而下面我们将再介绍3种使用代码获取环境变量的方式
1. char *env[]
其中其实main函数中还含有第3个参数,就是我们的env
#include <stdio.h>
#include <stdlib.h>
int main(int argc,char *argv[],char* env[])
{
//测试环境变量
//1.env
for(int i=0;env[i];i++)
{
printf("%s\n",env[i]);
}
return 0
}
运行结果:
2. char ** environ
实际上环境变量的组织方式是这样的,使用数组的方式存放
每个程序都会收到一张环境表,环境表是一个字符指针数组,每个指针指向一个以’\0’结尾的环境字符串
所以我们也可以通过二级指针char ** environ去访问到环境变量
#include <stdio.h>
#include <stdlib.h>
int main(int argc,char *argv[],char* env[])
{
//2.char ** environ
extern char ** environ;
for(int i=0;environ[i];i++)
{
printf("%s\n",environ[i]);
}
return 0;
}
运行结果:
3. getenv
系统调用接口:
参数:
- name:我们所需要查询的环境变量
返回值:
- 返回的是对应的环境变量的值
#include <stdio.h> #include <stdlib.h> W>int main(int argc,char *argv[],char* env[]) { //3.getenv printf("%s\n",getenv("HOME")); return 0; }
运行结果:
环境变量具有全局性
环境变量是具有全局性的,因为子进程可以继承父进程的环境变量,而我们的bash进程是每个执行程序的进程的父进程,自然会继承bash的环境变量,而如果执行程序时,我们又调用了fork,那么环境变量又会被子进程继承下去,所以可以说几乎是整个”用户层"都会受到环境变量的影响–所以说环境变量是具有全局性的。
验证方法:在命令行添加my_string,尝试在子进程能否访问到该变量
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("my_string:%s\n",getenv("my_string"));
return 0;
}
演示结果:
说明,环境变量确实是具有全局性的