作者:@小萌新
专栏:@Linux
作者简介:大二学生 希望能和大家一起进步!
本篇博客简介:简单介绍下进程的优先级 环境变量
进程优先级环境变量
- 进程的优先级
- 基本概念
- 如何查看优先级
- PRI与NI
- NI值的设置范围
- NI值如何修改
- 修改方式一 : 通过top指令修改优先级
- 修改方式二 : 通过renice指令修改优先级
- 进程优先级思维导图
- 进程的四个重要概念
- 环境变量
- 引出
- 基本概念
- 常见的环境变量
- 查看环境变量
- 三种环境变量的作用(不建议修改)
- PATH
- 方式一: 将我们的可执行文件放到PATH路径中
- 方式二: 将我们当前的路径加入到PATH路径当中
- HOME
- SHELL
- 环境变量相关指令
- 环境变量的组织方式
- main函数的参数
- 通过系统函数来获取环境变量
- 思维导图总结
进程的优先级
基本概念
- 什么是进程优先级?
cpu资源分配的先后顺序 就是指进程的优先权(priority)
- 优先级存在的原因?
优先级存在的原因本质上是因为资源的不足 在系统中表现为有多个进程却只有一个cpu
如何查看优先级
我们可以使用ps -l指令来查看进程
其中有五个进程是比较重要的 我们这里拿出来单独解释下
- UID 代表执行者的身份
- PID 代表进程的代号
- PPID 代表父进程的代号
- PRI 代表进程的优先级
- NI 代表这个进程的nice值 用来修正进程的优先级
PRI与NI
- PRI是进程的优先级 通俗点说就是程序被CPU执行的先后顺序 此值越小进程的优先级别越高
- NI值就是我们所要说的nice值了 其表示进程可被执行的优先级的修正数值
- PRI和NI值的关系符合下面的公式 PRI(new) = PRI (old)+ NI
- 当NI值为负值的时候 那么该程序将会优先级值将变小 优先级会变高
- 调整进程优先级 就是调整进程的nice值
- nice的取值范围是-20~19 一共四十个值
在Linux系统中 PRI(old)值默认为80 所以说Linux中的优先级为 PRI(new) = 80 + NI
NI值的设置范围
NI的设置范围是固定的 必须是-20~19 如果超出这个值 则设定的nice值会变为最接近这个区间的值
比如说我们设定NI值为-100 则它的值会被设置为-20
如果我们设定NI值为100 则它的值会被设置为19
为什么NI值的范围被设置成这样子
因为操作系统要尽量的保证每个进程的公平运行 如果我们可以随意将进程的优先级设置的很低那么操作系统就会倾向于执行这个进程 从而导致其他进程不能被很好的被cpu执行 所以说PRI值最好是在一个范围中
NI值如何修改
修改NI值实际上就是进程的优先级
对于NI值的修改 我们有两种方式
修改方式一 : 通过top指令修改优先级
top命令就相当于Windows操作系统中的任务管理器
我们调用top命令之后会出来这样子的界面
接下来我们按住 r 键 就可以它就会要求你输入需要调整NI值的进程PID
接下来我们输入PID之后回车 它就会让我们输入NI值
我们这里输入修改的NI值为15之后回车 按住q键 退出top
之后我们再次使用ps指令查看9188进程的优先级
我们可以看到 9188号进程的优先级确实变为75了 但是为什么进程号为 20236的优先级也变为95了呢?
这是因为20236是9188的子进程 会继承父进程的代码和数据
修改方式二 : 通过renice指令修改优先级
具体指令为renice + NI值 + 进程号
最后我们通过ps指令可以发现nice值被修改为了-20 最终的PRI值为60
此外需要注意的是 普通用户如果想要renice需要使用sudo指令 临时提升权限
进程优先级思维导图
进程的四个重要概念
- 竞争性: 系统进程数目众多 而CPU资源只有少量 甚至1个 所以进程之间是具有竞争属性的 为了高效完成任务 更合理竞争相关资源 便具有了优先级
- 独立性: 多进程运行 需要独享各种资源 多进程运行期间互不干扰
- 并行: 多个进程在多个CPU下分别 同时进行运行 这称之为并行
- 并发: 多个进程在一个CPU下采用进程切换的方式 在一段时间之内 让多个进程都得以推进 称之为并发
环境变量
引出
下面我们会有两段命令的执行来验证环境变量的存在
我们首先写出了ls命令 系统给我们列出来当前目录下的所有文件
我们在这里发现了一个可执行文件test
我们如果想要执行这个可执行文件的话必须要使用这样子的指令
现在的我们很容易理解 . 是代表当前目录的意思 / 是目录分隔符
所以说./代表的就是当前目录下 实际上就是给出了一个相对路径
让在这个相对路径中寻找一个名叫test的可执行文件
也就是说如果我们直接输入test命令 系统会不知道我们要干什么
通过前面的学习我们知道了指令实际上也是一个可执行文件
那为什么我们直接输入文件名就可以执行该文件呢?
这就是因为环境变量的存在
基本概念
环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数
由于它是在操作系统中的 所以一般是全局变量
常见的环境变量
- PATH: 指定命令的搜索路径
- HOME: 指定用户的主工作目录(即用户登录到Linux系统中的默认所处目录)
- SHELL: 当前Shell,它的值通常是/bin/bash
查看环境变量
我们在linux中可以使用echo命令来查看环境变量
我们可以查看到这里环境变量的地址有这五个
三种环境变量的作用(不建议修改)
PATH
我们前面引入环境变量的时候 抛出过一个问题 为什么我们系统的可执行文件我们就可以直接执行 而我们自己编译的可执行文件却不可以呢?
这个就是因为环境变量PATH的存在
我们首先查看下PATH的路径
我们发现PATH由于多条路径组成 两个路径之间使用冒号分隔
之后我们再查看下ls指令的所在位置
我们发现ls指令的可执行文件就放在PATH路径中
而我们的可执行文件之所以要指定位置的就是因为它们不再PATH路径中
那么如果想要让我们自己编译可执行文件直接运行不指定路径应该怎么办呢?
很显然我们这里有两种解决方式
方式一: 将我们的可执行文件放到PATH路径中
我们可以发现 将proc放到PATH路径之后就可以直接执行前面不加路径了
注意 这里的可执行文件名不能为test 否则就算加入了也什么都不会发生
方式二: 将我们当前的路径加入到PATH路径当中
这样子我们便把当前路径加入到PATH路径当中去了
我们可以使用如下代码验证
其中我们配置PATH是临时配置
而我们添加可执行文件到目录下确实永久配置的
所以试验完毕之后记得删除PATH中的可执行文件
HOME
任何一个用户在运行系统登录时都有自己的主工作目录(家目录) 环境变量HOME当中即保存的该用户的主工作目录
我们查看HOME目录使用如下命令
SHELL
我们在Linux操作系统当中所敲的各种命令 实际上需要由命令行解释器进行解释 而在Linux当中有许多种命令行解释器(例如bash、sh) 我们可以通过查看环境变量SHELL来知道自己当前所用的命令行解释器的种类
我们查看SHELL使用如下命令
环境变量相关指令
- echo 作用: 显示某个环境变量的值
例如我们可以通过这个指令查看PATH
- export 作用: 设置一个新的环境变量
例如我们可以多设置一个路径的环境变量
- env 作用: 显示所有环境变量
- set 作用: 显示本地定义的shell变量和环境变量
- unset 作用:清除环境变量
我们可以看到环境变量中有个myval
如果我们想要清除这个环境变量我们可以使用unset
清除了之后我们就找不到这个环境变量了
环境变量的组织方式
在linux中 环境变量是通过一张表组织起来的 如果我们使用c语言的知识去理解的话其实就是环境变量表就是一个二级指针
它指向一个一级指针数组 这里面放置着各种环境变量 最后的环境变量是NULL
main函数的参数
其实我们所调用的main函数是有参数的
它一共有三个参数 分别是 argc argv envp
其中argv是一个指针 它指向一个数组 里面储存的是char*类型的数据
argc是一个整数 它标识着argv中有效元素的个数
我们可以写下下面的代码来验证
我们首先来验证下argc的个数
假如我们main函数后面不带选项 那么此时argc的个数是多少呢?
我们发现它走了第一个条件
其实这也很好理解 因为在什么条件都没有的时候argv的数组中有一个本程序的地址
当我们对于argc 和 argv有了更深一步的认知之后我们就可以在我们编写的程序中加入选项做一些事
比如说我们可以写下下面的代码
如果我们后面所携带的参数不同 那么这个程序就会做不同的事情
下面是演示效果
大概的argv数组图如下所示
我们再来看看它的第三个参数 envp
我们前面说过了 它其实就是一个二级指针 指向一个数组 里面全部是char*类型的数据 也就是环境变量 数组中的最后一个数据为空
那么我们可以直接遍历之来获取环境变量
此外 我们还可以直接用二级指针 environ来获取环境变量
注意 libc中定义的全局变量environ指向环境变量表 environ没有包含在任何头文件中 所以在使用时要用extern进行声明
代码标识如下
运行结果如下
我们可以发现二者并没有很多差别
通过系统函数来获取环境变量
除了我们上面所说的方法之外我们还可以使用getenv系统函数来查看环境变量
具体使用代码如下所示
效果如下