九、进程的优先级
1. 基本概念
cpu资源分配的先后顺序,就是指进程的优先权(priority)。
优先权高的进程有优先执行权利。配置进程优先权对多任务环境的linux很有用,可以改善系统性能。还可以把进程运行到指定的CPU上,这样一来,把不重要的进程安排到某个CPU,可以大大改善系统整体性能
2.查看进程优先级
在linux或者unix系统中,用ps –l命令则会类似输出以下几个内容:
[mlg@VM-20-8-centos lesson2]$ ps -l
我们很容易注意到其中的几个重要信息,有下:
UID : 代表执行者的身份
PID : 代表这个进程的代号
PPID :代表这个进程是由哪个进程发展衍生而来的,亦即父进程的代号
PRI :代表这个进程可被执行的优先级,其值越小越早被执行
NI :代表这个进程的nice值
3.PRI & NI
PRI: 即进程的优先级,或者通俗点说就是程序被CPU执行的先后顺序, 此值越小 进程的优先级别越高;
NI: 就是我们所要说的nice值了,其表示进程可被执行的优先级的修正数值 ;
PRI值越小越快被执行,那么加入nice值后,将会使得PRI变为:PRI(new)=PRI(old)+nice
当nice值为负值的时候 ,那么该程序将会优先级值将变小,即其优先级会变高,则其越快被执行;
调整进程优先级,在Linux下,就是调整进程nice值; nice其取值范围是-20至19,一共40个级别;
注:Linux下,PRI(old)默认是80
4.如何更改进程的优先级
1.用top命令更改已存在进程的nice
top命令经常用来监控linux的系统状况,是常用的性能分析工具,能够实时显示系统中各个进程的资源占用情况。
[mlg@VM-20-8-centos lesson2]$ top
想要把ps这个进程的nice值修改了,我们可以在输入top命令后,输入“r”,此时会出现提示:
在这里输入你想要修改的进程的PID,回车之后
在这里输入你想要修改的nice值,回车之后,按q退出,进行查看
2.用renice命令更改已存在进程的nice
5.其他概念
竞争性 : 系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级
独立性 : 多进程运行,需要独享各种资源,多进程运行期间互不干扰
并行 : 多个进程在多个CPU下分别,同时进行运行,这称之为并行
并发 : 多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发
十、环境变量
1.基本概念
环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数
如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。
环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性。
2.常见的环境变量
PATH : 指定命令的搜索路径
HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
SHELL : 当前Shell,它的值通常是/bin/bash。
3.查看环境变量
我们可以通过echo命令来查看环境变量
[mlg@VM-20-8-centos lesson2]$ echo $PATH
1.测试PATH
我们在输入指令时(ls / pwd等)并没有输入相应的路劲,只要指令正确就一定能执行,但是我们生成的可执行程序却要加上 ./(当前路径下)才可以被执行。这主要是以为系统在环境变量中找不到你当前可执行程序相应的路径。
我们通过echo $PATH查看环境变量,发现有许多有路径,并且由(:)号隔开。当我们输入指令时会通过环境变量查找相应的路径。
如何让我们自己的可执行程序也想系统命令一样直接执行呢?
方法一:
直接将可执行程序拷贝到里面去,但是不推荐这样做,如果你添加了,忘记删除了,后期在执行某些指令时,突然多出一些东西。污染环境
方法二:
直接将可执行程序所在路径拷贝到里面去。通过export指令+环境变量的名(export PATH)对环境变量进行新的设置
[mlg@VM-20-8-centos lesson2]$ export PATH=/home/mlg/lesson2
但是这样设置覆盖原来的环境变量,导致很多指令都用不了了
其实也不用担心,我们只要退出在重新启动就恢复了
正确的做法:
[mlg@VM-20-8-centos ~]$ export PATH=$PATH:/home/mlg/lesson2
2.测试HOME
为什么每次登录不同的用户,所在的家目录都是不一样的,就是因为环境变量HOME
普通用户:
root用户:
3.测试SHELL
我们在命令行所输入的指令,都是由命令行解释器进行解释的。我们可以通过查看环境变量SHELL来知道自己当前所用的命令行解释器。
4.和环境变量相关的命令
1.echo命令
这个处理可以查看相关的环境的变量,还可以直接打印一些数据
2.export命令
设置一个新的环境变量,还可以将本地变量导出环境变量;所谓的本地变量就相当于我们在C/C++中定义一个变量;
3.env命令
显示所有环境变量
4.set命令
显示本地定义的shell变量和环境变量
5.unset命令
清除环境变量;处理环境变量外,还有本地变量,所谓的本地变量就相当于我们在C/C++中定义一个变量。如下图所示:
5.环境的组织方式
每个程序都会收到一张环境表,环境表是一个字符指针数组,每个指针指向一个以’\0’结尾的环境字符串。
6.通过代码获取环境变量
1.main函数命令行参数的了解
对于main函数我们已经很熟悉了,它其实可以带有参数的,你了解吗?main函数有三个参数
int main(int arge, char* argv[], char* envp[])//这里的三个参数就是命令行参数 {}
我们先了解一下前两个参数的作用
#include <stdio.h> int main(int argc, char* argv[]) { for(int i = 0; i < argc; ++i){ printf("argv[%d]:%s\n",i,argv[i]); } return 0; }
结合代码及运行结果可以看出,我们在命令行中只有一个命令,那么对于的数组(argv[ ])中就有一个元素(字符串“./myproc”),有多个携带的参数就有多个字符串。
我们这里想说明的是,当我们在命令行中敲出一个命令后通过带入不同的参数选项,会有不同的结果。我们通过模拟实现一下这样的效果。
#include <stdio.h> #include <string.h> int main(int argc, char* argv[]) { if(argc != 2){ printf("Using: %s -[a|h|ah]\n",argv[0]); return 1; } if(strcmp(argv[1],"-h") == 0){ printf("hello world!\n"); } else if(strcmp(argv[1],"-a") == 0){ printf("hello linux!\n"); } else if(strcmp(argv[1],"-ah") == 0){ printf("hello world!\n"); printf("hello linux!\n"); } else{ printf("hello C++!\n"); } return 0; }
通过上面的代码我们也实现出了通过指令加选项的操作达到不同的效果,指令有很多选项,用来完成同一个命令的不同子功能,选项的底层使用的就是命令行参数。
2.main函数的环境变量获取
main函数除了有命令行参数,还有环境变量,也就是第三个参数。它是用来获取环境变量的
#include <stdio.h> #include <string.h> int main(int argc, char* argv[], char* env[]) { for(int i = 0; env[i]; i++){ printf("%d->%s\n",i, env[i]); } return 0; }
3.通过第三方变量environ获取
这是系统提供的一个获取环境变量的第三方变量,是一个二级指针
#include <stdio.h> #include <string.h> int main() { extern char** environ; for(int i = 0; environ[i]; i++){ printf("%d->%s\n",i, environ[i]); } return 0; }
7.通过系统调用获取环境变量 (常用)
以上两种获取环境变量太过于麻烦,我们最长用的还是通过系统调用来获取环境变量。
使用getenv函数获取
#include <stdio.h> #include <stdlib.h> int main() { printf("%s\n",getenv("PATH")); printf("%s\n",getenv("HOME")); printf("%s\n",getenv("SHELL")); return 0; }
注:环境变量是具有全局属性的,可以被子进程继承下去
#include <stdio.h> #include <stdlib.h> int main() { char * env = getenv("MYENV"); if(env){ printf("%s\n", env); } return 0; }
直接查看,发现没有结果,说明该环境变量根本不存在
导出环境变量
export MYENV="hello world"
再次运行程序,发现结果有了!说明:环境变量是可以被子进程继承下去的!
我们的程序执行起来后(进程),其共享父进程bash的环境变量(bash的环境变量是系统给的),那么只有bash的环境变量有所改变,影响的就是全局。