目录
一、进程优先级
1、优先级概念
2、优先级特点
3、修改Linux下的优先级
二、进程切换
1、进程特性
2、进程切换
三、环境变量
1、基本概念
2、常见环境变量
3、查看环境变量方法
4、PATH环境变量
5、和环境变量相关的命令
6、环境变量的组织方式
7、通过代码如何获取环境变量
8、通过系统调用获取或设置环境变量
9、环境变量通常是具有全局属性的
一、进程优先级
1、优先级概念
- CPU 资源分配的先后顺序,就是指进程的优先权(priority);
- 优先权高的进程有优先执行权利。配置进程优先权对多任务环境的 Linux 很有用,可以改善系统性能;
- 还可以把进程运行到指定的 CPU 上,这样一来,把不重要的进程安排到某个 CPU,可以大大改善系统整体性能.
2、优先级特点
- 进程的优先级和状态一样,本质都是PCB里面的一个数字(也可能是多个数字),操作系统通过这些数字来辨别进程的状态和优先级;
- 通过 ps -al 指令可以查看到进程的详细信息,PRI 和 NI 的值合并在一起代表 Linux 进程的优先级。PRI 其实就是最终优先级,只不过它受 NI 值的调控。
输入 ps -l 命令后,会显示一下内容
此时可以注意到其中几个重要信息,有下:
- UID : 代表执行者的身份;
- PID : 代表这个进程的代号;
- PPID :代表这个进程是由哪个进程发展衍生而来的,亦即父进程的代号;
- PRI :代表这个进程可被执行的优先级,其值越小越早被执行;
- NI :代表这个进程的 nice 值。
- PRI 也还是比较好理解的,即进程的优先级,或者通俗点说就是程序被CPU执行的先后顺序,此值越小进程的优先级别越高。
- 那NI呢?就是我们所要说的nice值了,其表示进程可被执行的优先级的修正数值。
- PRI值越小越快被执行,那么加入nice值后,将会使得PRI变为:PRI(new)=PRI(old)+nice。
- 这样,当nice值为负值的时候,那么该程序将会优先级值将变小,即其优先级会变高,则其越快被执行。
- 所以,调整进程优先级,在Linux下,就是调整进程nice值,nice其取值范围是-20至19,一共40个级别。
Linux 给我们提供了修改 进程 优先级的权限,目的就是让我们对多任务运行进行合理处理,提高系统运行效率。
注意:(1)进程的nice值不是进程的优先级,他们不是一个概念,但是进程nice值会影响到进程的优先级变化;(2)可以理解nice值是进程优先级的修正修正数据。
3、修改Linux下的优先级
先输入top,进入top后,按‘r’,然后输入进程PID,输入nice值。
(1)输入 top 指令
(2) 输入 r
(3) 输入进程的 id
(4)输入 NI 值(例如:NI = -10)
结果:PRI(新的) = PRI(旧的) + NI(-10) = 70
注意:普通用户无法直接修改NI的值,必须切换成root用户或者使用sudo提权执行top指令。
二、进程切换
1、进程特性
- 竞争性: 系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高 效完成任务,更合理竞争相关资源,便具有了优先级;
- 独立性: 多进程运行,需要独享各种资源,多进程运行期间互不干扰;
- 并行: 多个进程在多个CPU下分别,同时进行运行,这称之为并行;
- 并发: 多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发.
2、进程切换
(1) 一个CPU里面存在一套硬件寄存器,寄存器分为用户可见的寄存器,用户不可见的寄存器。
(2) 计算机调度某个进程时,CPU 会把这个进程的 PCB 地址加载到某个寄存器,也就是说,CPU内有寄存器可以只找到进程的PCB地址。
(3) CPU里有一个 eip 寄存器(PC指针),指向当前执行指令的下一条指令的地址。
(4) 当进程在运行的时候,一定会产生非常多的临时数据,这些临时数据只属于当前进程,虽然CPU内部只有一套寄存器硬件,但是寄存器里面保存的数据是属于当前进程的,寄存器硬件和寄存器内的数据是两码事。
(5) 进程在调度的时候占有CPU,但是却不是一直占有到进程结束,进程都有自己的时间片!因为时间片的存在,进程会出现没有被执行完就被拿下去的情况。
(6) 在进程重新被CPU调度的时候,CPU必须知道上一次这个进程运行到哪,当进程被换下去的时候,进程的运行信息会被存在操作系统里面,以便下次CPU重新调度时进程能够正常运行,这叫做进程的上下文保护。当进程被CPU重新调度上来时,首先要做的第一件事情就是读取操作系统中进程运行的相关数据,这叫做进程的上下文恢复。
三、环境变量
1、基本概念
- 环境变量一般是指在操作系统中用来指定操作系统运行环境的一些参数。如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但 是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找;
- 环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性。
2、常见环境变量
- PATH : 指定命令的搜索路径;
- HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录;
- SHELL : 当前Shell,它的值通常是/bin/bash。
3、查看环境变量方法
我们可以通过指令 echo $NAME 来查看当前环境变量信息(NAME :环境变量名)
//查看用户信息
echo $USER
//查看PATH环境变量
echo $PATH
4、PATH环境变量
(1)直接添加PATH环境变量
(2)使用 export 命令添加
注意:我们不能直接写成这样:export PATH=/home/xqh/dir,这样会导致把系统默认的环境变量PATH覆盖掉,我们默认的那些指令就不能直接使用了,只能通过指定路径的方式来使用(关掉Xshell,重新打开,就恢复了)。
5、和环境变量相关的命令
- echo: 显示某个环境变量值;
- export: 设置一个新的环境变量;
- env: 显示所有环境变量;
- unset: 清除环境变量;
- set: 显示本地定义的shell变量和环境变量。
1、查看所有的环境变量:env 指令
2、也可以通过set 指令来查看环境变量表,不过还会多很多信息,包括本地环境变量等。
环境变量 具有全局属性,可以供所有子进程共享,倘若我们不想让 环境变量 被共享,可以设置本地变量。
$ TEST=private //可以直接在命令行中添加本地变量。
现在的 TEST 环境变量是不被子进程共享的。
$ unset TEST //移除已设置的本地环境变量
想让 TEST 进入 环境变量表,只用加上 export 关键字。
$ export TEST=public // 此时环境变量已经加入到环境变量表中。
6、环境变量的组织方式
环境变量表是以指针数组的形式存储的。
7、通过代码如何获取环境变量
我相信大家心中想的 main 函数是无参的形式,实际上main函数是可以传参的,并且最多可以传 3 个参数。
int argc, char *argv[], char *env[]
- 我们可以通过上面的3个参数来获取环境变量。
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char* argv[], char* env[])
{
int i = 0;
for (; env[i]; i++)
{
printf("%s\n", env[i]);
}
return 0;
}
- 还可以通过第三方变量 environ 获取
#include <stdio.h>
#include <unistd.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]);
}
return 0;
}
注意:libc 中定义的全局变量 environ 指向环境变量表,environ 没有包含在任何头文件中,所以在使用时要用 extern 声明。
8、通过系统调用获取或设置环境变量
- getenv
- putenv
#include <stdio.h>
#include <stdlib.h>
int main()
{
char* env = getenv("PATH");
printf("%s\n", env);
return 0;
}
通过以上运行,可以看到既可以用函数 getenv() 来获取,也可以使用 echo $环境变量名 来获取。
9、环境变量通常是具有全局属性的
- 环境变量通常具有全局属性,可以被子进程继承下去。
#include <stdio.h>
#include <stdlib.h>
int main()
{
char* env = getenv("MYENV");
if (env)
{
printf("%s\n", env);
}
return 0;
}
运行如下:
直接查看,发现没有结果,说明该环境变量根本不存在。
然后,导出环境变量 export MYENV="hello world" ,此时再次运行程序,发现有结果了!
说明:环境变量是可以被子进程继承下去的!
本文要是有不足的地方,欢迎大家在下面评论,我会在第一时间更正。
老铁们,记着点赞加关注!!!