Linux进程学习【环境变量】进程优先级
进程优先级的基本概念
在 Linux 中,每个进程都有一个优先级,操作系统根据这个优先级来决定进程的执行顺序。优先级越高,进程的执行就越频繁。通常,进程优先级是由以下两个部分构成:
-
静态优先级(PRI):
-
这是进程在系统启动时设置的优先级,通常是一个数字值,范围在 0 到 139 之间。较低的数字代表较高的优先级,反之亦然。
-
默认情况下,大多数进程的优先级值为 80。优先级越低,表示该进程的优先级越高。
-
-
动态优先级(NI):
-
NI(nice value) 是一个动态调整值,通常范围为 -20 到 19。较低的值表示较高的优先级,较高的值表示较低的优先级。
nice
值决定了进程优先级的调整幅度。 -
例如,如果一个进程的
nice
值为 -10,它的优先级比默认值 80 高。而如果nice
值为 10,它的优先级则较低。
-
CPU 资源是有限的,需要合理分配
Linux
给我们提供了修改进程
优先级的权限,目的就是让我们对多任务运行进行合理处理,提高系统运行效率
我们可以通过 ps
指令查看进程优先级情况
//注:其中的 myfile 是可执行程序名
$ ps -al | head -1 && ps -al | grep myfile //查看进程优先级信息
🖋️优先级修改
进程优先级
可以被修改,但很少有人会主动修改
修改步骤
- 输入
top
指令进入任务管理器 - 输入
r
进入修改模式 - 再根据想要修改的进程,输入
PID
- 最后输入
NI
值,完成修改
注意:
NI
值区间为[-20, 19]
,设置时超出部分无效- 修改优先级时,
最终优先级
=初始优先级
+NI值
,优先级的修改行为并不是连续的,每次都是在最开始的基础上进行修改(默认为 80) - 调度器不允许存在
优先级失衡
的情况,因此优先级修改不能太激进。
下面来简单小结一下进程的特点
- 竞争性:CPU 资源有限,
进程
间存在竞争 - 独立性:
进程
是相互独立运行的,互不干扰 (重要) - 并行:多个
进程
可以在多个 CPU 上同时运行 - 并发:在一个 CPU 下采用
进程
切换的方式运行多个进程
什么是环境变量?
环境变量(Environment Variables)是操作系统用来存储系统配置信息的变量,它们决定了操作系统和程序的运行环境。简单来说,环境变量存储了影响系统运行的一些关键信息,例如系统路径、用户信息、程序配置等。它们对程序的运行至关重要,尤其是在编译、运行及配置程序时。
一般是指在操作系统中用来指定操作系统运行环境的一些参数。
例如在编译程序时,我们是不关心动态库位于什么地方,编译器链接时也只需要通过对应的 环境变量 就能找到动态库进行链接.
环境变量 有着自己的特殊用途,还有有些具有全局属性,可以供所有 进程 共享。
环境变量 有很多个,把它们聚在一起管理,就构成了 环境变量列表
环境变量列表 中的常见 环境变量:
- PATH 系统命令搜索路径
- USER 当前用户名
- PWD 当前所处路径
我们可用通过指令 echo $NAME
查看当前环境变量信息(NAME
指环境变量名)
//比如查看用户信息
$ echo $USER
$ env
🖋️环境变量列表
下面来看看 环境变量列表
长什么样
通过指令查看
$ env
也可以通过
set
指令查看 环境变量表
,不过 set
指令显示的内容比 env
多得多,因为 set
还会显示 本地环境变量
信息
$ set //显示更加丰富的环境变量表
- Linux 中的各种指令都是用 C语言 编写的程序,所以:运行指令 == 运行程序
- PATH 环境变量中有存储各种指令(程序)的路径,当我们直接输入指令时,OS会根据 PATH 提供的路径搜索程序,找到了就会直接运行对应指令(程序)
- 而我们自己编写的程序则是需要通过 ./可执行程序 的方式运行,因为此时路径不被包含在 PATH 变量中。
- 总之:PATH 存储路径中若包含程序,可以直接通过程序名运行程序这就是各种指令,如 ls、pwd、touch 的运行原理。
我们可以通过这一特性,将自己的可执行程序路径添加到 PATH
变量中
//注意:路径为绝对路径
//不能写成 export PATH=路径 这样会把所有指令都覆盖
$ export PATH=$PATH:/home/Yohifo/linux/Explore/code/Test_2_21
现在可以像指令一样直接运行程序
注意: 普通用户添加的环境变量只有本次登录有效,下次再登录时,环境变量列表会被重置
普通用户修改 环境变量列表 没什么大问题,但 root 需要谨慎了,避免造成严重后果
1. 普通用户的环境变量生效位置
普通用户设置的环境变量,如果你想让它们在 每次登录 或 每次启动操作系统时 都生效,必须把环境变量添加到正确的配置文件中。比如:
~/.bashrc
:适用于 非登录 shell,在打开终端时加载。
~/.bash_profile
或~/.profile
:适用于 登录 shell,在登录操作系统时加载(例如 SSH 登录)。如果你只在某个文件(如
~/.bashrc
)中设置了环境变量,并且没有在 登录时加载 它,那么下次你打开 SSH 或重新登录操作系统时,环境变量就不会生效。2. 问题分析:环境变量没有在重新启动后生效
如果你在
~/.bashrc
中设置了环境变量,但它在 下次登录 或 操作系统重新启动后 没有生效,这可能是由于以下原因:
~/.bashrc
只会在打开新的终端会话时生效,并且 不会在登录时自动加载。在 SSH 登录时,默认情况下只会加载~/.bash_profile
或~/.profile
,而~/.bashrc
需要显式地通过~/.bash_profile
来加载。如果你只在
~/.bashrc
中添加了环境变量,而没有在~/.bash_profile
中引用它,登录操作时,~/.bashrc
就不会被加载,导致环境变量没有生效。
除此之外,我们还可以把程序写在 /usr/bin 目录下,此时也是可以直接通过程序名运行程序的
如上就是安装、卸载应用原理
🖋️添加环境变量
shell
可以读取到命令和命令行,我们可以直接通过命令的方式添加 环境变量
先来看看比较简单的 本地变量
添加
环境变量表
具有全局属性,可以供所有子进程共享,倘若我们不想让 环境变量
被共享,可以设置 本地变量
$ TEST=private //可以直接在命令行中添加本地变量
现在的 TEST
环境变量是不被子进程共享的
如果想删除已经设置的 本地环境变量
,可以通过 unset NAME
移除设置
$ unset TEST //移除已设置的本地环境变量
想让 TEST
进入 环境变量表
也很简单,只需要加上关键字 export
$ export TEST=public //此时环境变量已进入环境变量表
🖋️获取环境变量
🖋️三个参数
main 函数中有三个参数,分别是:
- int argc 传入程序中的元素数,./程序名 算一个
- char* argv[] 传入程序中的元素表,由 bash 制作,传给 main 函数
- char* envp[] 环境变量表,所谓全局性就是指 main 函数可以通过此参数获取到环境变量表的信息
1. 通过 environ
全局变量获取环境变量
environ
是一个全局变量(char**
类型),它是一个指向环境变量列表的指针数组。这个列表包含了所有环境变量的字符串,每个字符串以 KEY=VALUE
的格式存储。
例如,如果你要查看系统的环境变量,可以通过遍历 environ
来实现:
#include <iostream>
#include <cstdlib> // 需要引用 stdlib.husing namespace std;extern char** environ; // 声明 environ,全局环境变量指针int main(int argc,char* argv[] ,char* envp[]) {int pos = 0;cout << argv[pos] << endl;while (environ[pos] != nullptr) { // environ 是一个以 NULL 结束的数组cout << environ[pos] << endl; // 输出每个环境变量pos++;}return 0;
}
解释:
默认会有一个参数就是文件名字符串。
-
environ
是一个指向char*
的数组,数组中的每个元素是一个环境变量。 -
每个环境变量以
KEY=VALUE
形式存在,因此你可以通过遍历environ
来查看所有环境变量。
2. 通过 getenv()
函数获取单个环境变量
getenv()
是标准 C 库提供的一个函数,它可以用来获取单个环境变量的值。这个函数非常常见,通常用于获取常用的环境变量,比如当前工作目录 (PWD
)、用户名称 (USER
) 等。
#include <iostream>
#include <cstdlib> // 需要引用 stdlib.husing namespace std;int main() {// 获取当前工作目录const char* pwd = getenv("PWD");if (pwd != nullptr) {cout << "当前目录: " << pwd << endl;} else {cout << "环境变量 PWD 不存在" << endl;}// 获取当前用户名const char* user = getenv("USER");if (user != nullptr) {cout << "当前用户名: " << user << endl;} else {cout << "环境变量 USER 不存在" << endl;}return 0;
}
解释:
-
getenv("VARIABLE_NAME")
返回环境变量的值,如果指定的环境变量不存在,则返回nullptr
。 -
这种方式适用于你只关心某一个环境变量的情况。
3. 通过 main
函数中的 envp[]
获取环境变量
在 C 或 C++ 程序中,main
函数通常可以接收三个参数,其中第三个参数是 envp[]
,它是一个指向环境变量的指针数组。和 environ
类似,envp[]
也是一个数组,每个元素都是一个 KEY=VALUE
的字符串。
#include <iostream>
#include <cstdlib> // 需要引用 stdlib.husing namespace std;int main(int argc, char* argv[], char* envp[]) {// 输出环境变量int pos = 0;while (envp[pos] != nullptr) {cout << envp[pos] << endl; // 输出每个环境变量pos++;}return 0;
}
解释:
-
envp[]
是一个指向字符串的数组,数组中的每个字符串也是一个环境变量。 -
这种方式和
environ
很相似,但是它通过main
函数的参数传递,更加灵活。
结论
获取环境变量在 Linux 系统中非常常见,尤其是在编写需要根据环境配置的程序时。你可以通过以下三种方式来获取环境变量:
-
environ
:直接访问全局环境变量。 -
getenv()
:获取单个环境变量的值。 -
envp[]
:通过main
函数的参数获取环境变量。
这些方法各有适用场景,具体使用哪种方式取决于你的需求。如果你想获取所有环境变量,environ
或 envp[]
是更方便的选择;如果你只需要某个特定环境变量的值,getenv()
是最直接的方式。