Linux 环境变量&&进程优先级

1.环境变量

1.1 基本概念

  1. 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数
  2. 如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。
  3. 环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性。
  4. 环境变量会被继承下来,父进程的环境变量会继承给子进程。

1.2 常见环境变量

  1. PATH : 指定命令的搜索路径
  2. HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
  3. SHELL : 当前Shell,它的值通常是/bin/bash。

1.3 查看环境变量

env指令可以查看所有环境变量。

echo+$环境变量名称 :可以查看环境变量。

1.4 进一步了解环境变量

为什么我们输入ls,cd,pwd这些指令的时候,就可以直接被执行,但是我们的二进制文件却需要输入./文件名才会被执行呢?

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

我们可以输入export PATH=$PATH:/home/wjp/lee,把路径添加到系统的搜索路径中,这样子再执行的时候就会去这条路径里面寻找。

export PATH=/home/wjp/lee,如果这样子写的话就会变成覆盖掉了,输入其他指令都不会生效。

如果覆盖了也没有关系,普通用户的操作在重启后就会恢复原来的路径,切换到root用户的话要小心使用。

1.5 本地变量

当我们直接将1234赋值给myval,就是一个本地变量,是不会被继承的,同时也不属于环境变量,在env里面也查找不到这个环境变量,也就是这个本地变量是只属于bash的。

通过在环境变量前面加是export可以将它变为环境变量。

set指令可以把所有的本地变量和环境变量全部显示出来。

1.6 环境变量的相关指令

  1. echo: 显示某个环境变量值
  1. export: 设置一个新的环境变量
  1. env: 显示所有环境变量

  2. unset: 清除环境变量

环境变量中找不到a了。

  1. set: 显示本地定义的shell变量和环境变量

1.7 环境变量的获取

每个程序都会收到一个环境变量表,环境表是一个字符指针数组,每一个指针都指向一个以'\0'结尾的环境字符表。

1.7.1 通过代码获取环境变量

int argc 传入程序中的元素数,./程序名 算一个

char* argv[] 传入程序中的元素表,由 bash 制作,传给 main 函数

cpp 复制代码
  1 #include<stdio.h>
  2 #include<unistd.h>
  3 #include<sys/types.h>
  4 int main(int argc,char*argv[])
  5 {
  6         int i=0;
  7         for(;argv[i];i++)
  8         {
  9                 printf("env[%d]->%s\n",i,argv[i]);
 10         }
 11         return 0;
 12 }

所以我们在命令行输入运行指令,以空格为分隔符,bash会把这些字符都传入给argv数组,我们也就可以把它们一个一个打印出来,argc表示个数。

除了命令行参数表,mian函数还有一个char* env[] 环境变量表,所谓全局性就是指 main 函数可以通过此参数获取到环境变量表的信息。

我们同样可以通过上面的方法,把环境表都打印出来。

cpp 复制代码
 1 #include<stdio.h>
  2 #include<unistd.h>
  3 #include<sys/types.h>
  4 int main(int argc,char*argv[],char*env[])
  5 {
  6         int i=0;
  7         for(;env[i];i++)
  8         {
  9                 printf("env[%d]->%s\n",i,env[i]);
 10         }
 11         return 0;
 12 }

1.7.2 通过第三方变量environ获取

cpp 复制代码
#include <stdio.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声明。

1.7.3 通过系统调用获取环境变量

前面两个都是获取了整个的环境变量表,如果我们需要在代码中获取单一的环境变量可以使用getenv()函数

cpp 复制代码
int main()
{
 printf("%s\n", getenv("PATH"));
 return 0;
}

1.8 常规命令和内建命令

前面我们提到本变量是不会被继承的,那么bash不是通过创建进程来帮助自己实现指令的吗,echo函数的实现难道不是bash创建子进程来帮助完成的吗?

答案是不是的,指令页分为两种:

常规命令:bash通过创建子进程来完成的。

内建命令:bash不创建子进程,而是自己亲自执行,类似于bash调用了自己写的函数,或者系统调用函数。

2. 进程优先级

cpu资源分配的先后顺序,就是指进程的优先权(priority)。

优先权高的进程有优先执行权利。配置进程优先权对多任务环境的linux很有用,可以改善系统性能。

还可以把进程运行到指定的CPU上,这样一来,把不重要的进程安排到某个CPU,可以大大改善系统整体性能。

我们很容易注意到其中的几个重要信息,有下:

  1. UID : 代表执行者的身份
  2. PID : 代表这个进程的代号
  3. PPID :代表这个进程是由哪个进程发展衍生而来的,亦即父进程的代号
  4. PRI :代表这个进程可被执行的优先级,其值越小越早被执行
  5. NI :代表这个进程的nice值

PRI and NI

  1. PRI也还是比较好理解的,即进程的优先级,或者通俗点说就是程序被CPU执行的先后顺序,此值越小进程的优先级别越高
  2. 那NI呢?就是我们所要说的nice值了,其表示进程可被执行的优先级的修正数值
  3. PRI值越小越快被执行,那么加入nice值后,将会使得PRI变为:PRI(new)=PRI(old)+nice,
  4. 这样,当nice值为负值的时候,那么该程序将会优先级值将变小,即其优先级会变高,则其越快被执行
  5. 所以,调整进程优先级,在Linux下,就是调整进程nice值
  6. nice其取值范围是-20至19,一共40个级别。
  7. 所以最后就看PRI(new)越小优先级就越高

PRI vs NI

  1. 需要强调一点的是,进程的nice值不是进程的优先级,他们不是一个概念,但是进程nice值会影响到进程的优先级变化。
  2. 可以理解nice值是进程优先级的修正修正数据

2.1 top指令

进入top后按"r"-->输入进程PID-->输入nice值

操作系统的分配已经是最优的方法了,所以我们就不应该过多的去修改。

注意:

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

一些其他概念

竞争性: 系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级

独立性: 多进程运行,需要独享各种资源,多进程运行期间互不干扰

并行: 多个进程在多个CPU下分别,同时进行运行,这称之为并行

并发: 多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发

寄存器:寄存器有很多种,去保存进程里面很多相关的数据(相当于进程的上下文),当进程被切换,需要做的有保存上下文,和恢复上下文,这样子 cpu 才会知道你接下来该运行哪个部分,和上面的上次运行时的数据,保存上下文,进程要时间片时间到了后,要脱离 cpu,进程的 pcb 会构建一个结构体,里面去存放上下文,到再次要运行的时候,再把数据放到寄存器上面(这个是当前只能这么理解)。

相关推荐
marsh02064 分钟前
43 openclaw熔断与降级:保障系统在异常情况下的可用性
java·运维·网络·ai·编程·技术
摇滚侠7 分钟前
Docker 如何查询挂载的目录
运维·docker·容器
勇闯逆流河1 小时前
【Linux】linux进程控制(进程池的详解与实现)
linux·运维·服务器
zhangfeng11331 小时前
部署到服务器上 宝塔系统 使用宝塔在线编辑器 FTP 批量上传 Git 部署 打包上传 codebudyy 编程程序开发
服务器·git·编辑器
WJ.Polar2 小时前
Scapy基本应用
linux·运维·网络·python
lljss20202 小时前
1. NameServer 域名服务器---NS
linux·服务器·前端
萧行之3 小时前
Ubuntu+Windows双系统:解决GRUB不显示Windows启动项、一闪而过问题
linux·windows·ubuntu
数智顾问3 小时前
(123页PPT)华为流程管理体系精髓提炼(附下载方式)
运维·华为
Yupureki4 小时前
《Linux网络编程》5.HTTPS协议
linux·网络·https
网络工程小王4 小时前
【LCEL 链式调用详解】调用篇-2
java·服务器·前端·数据库·人工智能