Linux进程学习【环境变量】&&进程优先级

进程优先级的基本概念

在 Linux 中,每个进程都有一个优先级,操作系统根据这个优先级来决定进程的执行顺序 。优先级越高,进程的执行就越频繁。通常,进程优先级是由以下两个部分构成:

  • 静态优先级(PRI)

    • 这是进程在系统启动时设置的优先级,通常是一个数字值,范围在 0 到 139 之间。较低的数字代表较高的优先级,反之亦然。

    • 默认情况下,大多数进程的优先级值为 80 。优先级越低,表示该进程的优先级越高。

  • 动态优先级(NI)

    • NI(nice value) 是一个动态调整值,通常范围为 -20 到 19。较低的值表示较高的优先级,较高的值表示较低的优先级。nice 值决定了进程优先级的调整幅度。

    • 例如,如果一个进程的 nice 值为 -10,它的优先级比默认值 80 高。而如果 nice 值为 10,它的优先级则较低。

CPU 资源是有限的,需要合理分配

  • Linux 给我们提供了修改 进程 优先级的权限,目的就是让我们对多任务运行进行合理处理,提高系统运行效率

我们可以通过 ps 指令查看进程优先级情况

cpp 复制代码
//注:其中的 myfile 是可执行程序名
$ ps -al | head -1 && ps -al | grep myfile	//查看进程优先级信息
🖋️优先级修改

进程优先级 可以被修改,但很少有人会主动修改

修改步骤

  • 输入 top 指令进入任务管理器
  • 输入 r 进入修改模式
  • 再根据想要修改的进程,输入 PID
  • 最后输入 NI 值,完成修改

注意:

  • NI值区间为 [-20, 19],设置时超出部分无效
  • 修改优先级时,最终优先级 = 初始优先级 + NI值,优先级的修改行为并不是连续的,每次都是在最开始的基础上进行修改(默认为 80)
  • 调度器不允许存在 优先级失衡 的情况,因此优先级修改不能太激进。

下面来简单小结一下进程的特点

  • 竞争性:CPU 资源有限,进程 间存在竞争
  • 独立性:进程 是相互独立运行的,互不干扰 (重要)
  • 并行:多个 进程 可以在多个 CPU 上同时运行
  • 并发:在一个 CPU 下采用 进程 切换的方式运行多个 进程
什么是环境变量?

环境变量(Environment Variables)是操作系统用来存储系统配置信息的变量,它们决定了操作系统和程序的运行环境。简单来说,环境变量存储了影响系统运行的一些关键信息,例如系统路径、用户信息、程序配置等。它们对程序的运行至关重要,尤其是在编译、运行及配置程序时。

一般是指在操作系统中用来指定操作系统运行环境的一些参数。

例如在编译程序时,我们是不关心动态库位于什么地方,编译器链接时也只需要通过对应的 环境变量 就能找到动态库进行链接.

环境变量 有着自己的特殊用途,还有有些具有全局属性,可以供所有 进程 共享。
环境变量 有很多个,把它们聚在一起管理,就构成了 环境变量列表

环境变量列表 中的常见 环境变量:

  1. PATH 系统命令搜索路径
  2. USER 当前用户名
  3. PWD 当前所处路径

我们可用通过指令 echo $NAME 查看当前环境变量信息(NAME 指环境变量名)

cpp 复制代码
//比如查看用户信息
$ echo $USER	
cpp 复制代码
$ env
🖋️环境变量列表

下面来看看 环境变量列表 长什么样

通过指令查看

cpp 复制代码
$ env

也可以通过 set 指令查看 环境变量表,不过 set 指令显示的内容比 env 多得多,因为 set 还会显示 本地环境变量 信息

cpp 复制代码
$ set	//显示更加丰富的环境变量表
  • Linux 中的各种指令都是用 C语言 编写的程序,所以:运行指令 == 运行程序
  • PATH 环境变量中有存储各种指令(程序)的路径,当我们直接输入指令时,OS会根据 PATH 提供的路径搜索程序,找到了就会直接运行对应指令(程序)
  • 而我们自己编写的程序则是需要通过 ./可执行程序 的方式运行,因为此时路径不被包含在 PATH 变量中。
  • 总之:PATH 存储路径中若包含程序,可以直接通过程序名运行程序这就是各种指令,如 ls、pwd、touch 的运行原理。

我们可以通过这一特性,将自己的可执行程序路径添加到 PATH 变量中

cpp 复制代码
//注意:路径为绝对路径
//不能写成 export PATH=路径	这样会把所有指令都覆盖
$ export PATH=$PATH:/home/Yohifo/linux/Explore/code/Test_2_21

现在可以像指令一样直接运行程序

注意: 普通用户添加的环境变量只有本次登录有效,下次再登录时,环境变量列表会被重置

普通用户修改 环境变量列表 没什么大问题,但 root 需要谨慎了,避免造成严重后果

  1. 普通用户的环境变量生效位置

普通用户设置的环境变量,如果你想让它们在 每次登录每次启动操作系统时 都生效,必须把环境变量添加到正确的配置文件中。比如:

  • ~/.bashrc :适用于 非登录 shell,在打开终端时加载。

  • ~/.bash_profile~/.profile :适用于 登录 shell,在登录操作系统时加载(例如 SSH 登录)。

如果你只在某个文件(如 ~/.bashrc)中设置了环境变量,并且没有在 登录时加载 它,那么下次你打开 SSH 或重新登录操作系统时,环境变量就不会生效。

  1. 问题分析:环境变量没有在重新启动后生效

如果你在 ~/.bashrc 中设置了环境变量,但它在 下次登录操作系统重新启动后 没有生效,这可能是由于以下原因:

  • ~/.bashrc 只会在打开新的终端会话时生效 ,并且 不会在登录时自动加载 。在 SSH 登录时,默认情况下只会加载 ~/.bash_profile~/.profile ,而 ~/.bashrc 需要显式地通过 ~/.bash_profile 来加载。

  • 如果你只在 ~/.bashrc 中添加了环境变量,而没有在 ~/.bash_profile 中引用它,登录操作时,~/.bashrc 就不会被加载,导致环境变量没有生效。

除此之外,我们还可以把程序写在 /usr/bin 目录下,此时也是可以直接通过程序名运行程序的

如上就是安装、卸载应用原理

🖋️添加环境变量

shell 可以读取到命令和命令行,我们可以直接通过命令的方式添加 环境变量

先来看看比较简单的 本地变量 添加
环境变量表 具有全局属性,可以供所有子进程共享,倘若我们不想让 环境变量 被共享,可以设置 本地变量

cpp 复制代码
$ TEST=private	//可以直接在命令行中添加本地变量

现在的 TEST 环境变量是不被子进程共享的

如果想删除已经设置的 本地环境变量,可以通过 unset NAME 移除设置

cpp 复制代码
$ unset TEST	//移除已设置的本地环境变量

想让 TEST 进入 环境变量表 也很简单,只需要加上关键字 export

cpp 复制代码
$ export TEST=public	//此时环境变量已进入环境变量表
🖋️获取环境变量

🖋️三个参数

main 函数中有三个参数,分别是:

  • int argc 传入程序中的元素数,./程序名 算一个
  • char* argv[] 传入程序中的元素表,由 bash 制作,传给 main 函数
  • char* envp[] 环境变量表,所谓全局性就是指 main 函数可以通过此参数获取到环境变量表的信息
  1. 通过 environ 全局变量获取环境变量

environ 是一个全局变量**(char** 类型)** ,它是一个指向环境变量列表的指针数组。这个列表包含了所有环境变量的字符串**,每个字符串以 KEY=VALUE 的格式存储**。

例如,如果你要查看系统的环境变量,可以通过遍历**environ** 来实现:

cpp 复制代码
#include <iostream>
#include <cstdlib> // 需要引用 stdlib.h

using 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 来查看所有环境变量。


  1. 通过 getenv() 函数获取单个环境变量

getenv() 是标准 C 库提供的一个函数,它可以用来获取单个环境变量的值。这个函数非常常见,通常用于获取常用的环境变量,比如当前工作目录 (PWD)、用户名称 (USER) 等。

cpp 复制代码
#include <iostream>
#include <cstdlib> // 需要引用 stdlib.h

using 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

  • 这种方式适用于你只关心某一个环境变量的情况。


  1. 通过 main 函数中的 envp[] 获取环境变量

在 C 或 C++ 程序中,main 函数通常可以接收三个参数,其中第三个参数是 envp[],它是一个指向环境变量的指针数组。和 environ 类似,envp[] 也是一个数组,每个元素都是一个 KEY=VALUE 的字符串。

cpp 复制代码
#include <iostream>
#include <cstdlib> // 需要引用 stdlib.h

using 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 系统中非常常见,尤其是在编写需要根据环境配置的程序时。你可以通过以下三种方式来获取环境变量:

  1. environ:直接访问全局环境变量。

  2. getenv():获取单个环境变量的值。

  3. envp[] :通过 main 函数的参数获取环境变量。

这些方法各有适用场景,具体使用哪种方式取决于你的需求。如果你想获取所有环境变量,environenvp[] 是更方便的选择;如果你只需要某个特定环境变量的值,getenv() 是最直接的方式。

相关推荐
浪裡遊22 分钟前
跨域问题(Cross-Origin Problem)
linux·前端·vue.js·后端·https·sprint
Johny_Zhao1 小时前
OpenStack 全套搭建部署指南(基于 Kolla-Ansible)
linux·python·信息安全·云计算·openstack·shell·yum源·系统运维
2401_867021901 小时前
文件缓冲区(IO与文件 ·III)(linux/C)
linux·运维·服务器·c语言
刘某的Cloud1 小时前
rabbitmq常用命令
linux·运维·分布式·rabbitmq·系统
悄悄敲敲敲2 小时前
Linux:进程间通信->命名管道
linux·运维·服务器
望获linux2 小时前
智能清洁机器人中的实时操作系统应用研究
大数据·linux·服务器·人工智能·机器人·操作系统
io无心2 小时前
Docker绑定端口报错
运维·docker·容器
yuhouxiyang3 小时前
学习海康VisionMaster之路径提取
学习·计算机视觉
悄悄敲敲敲4 小时前
Linux:进程间通信->共享内存
linux·运维·服务器
PLUS_WAVE4 小时前
CogCoM: A Visual Language Model with Chain-of-Manipulations Reasoning 学习笔记
学习·语言模型·大模型·cot·vlm·推理模型·reasoning