目录
一、环境变量
1、基本概念
- 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数
- 如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。
- 环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性
2、常见的环境变量
- PATH : 指定命令的搜索路径
- HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
- SHELL : 当前Shell,它的值通常是/bin/bash。
3、查看环境变量的方法
echo $NAME //NAME:你的环境变量名称
4、和环境变量相关的命令
echo: 显示某个环境变量值
export: 设置一个新的环境变量
env: 显示所有环境变量
unset: 清除环境变量
set: 显示本地定义的shell变量和环境变量
二、环境表
每一个程序其实都需要环境变量,那么环境变量在哪存着呢?
环境变量存储在一张表里,叫环境表,环境表是一个指针数组,数组里的每个指针指向一个环境变量
每个程序都会收到一张环境表,环境表是一个字符指针数组,每个指针指向一个以’\0’结尾的环境字符串
1、通过代码如何获取环境变量
①命令行第三个参数
main 函数是有具体参数的,那这个参数代表什么意思呢?
【解答】main函数对应一个程序进程,平常的指令也是一个程序进程,程序的实现从底层来说也是用main函数实现的。main函数后面的参数是用来命令选项的。
- 其中第一个参数argc 是命令的名称。
- 第二个参数char* argv[]是命令的参数。
- 第三个参数char* env[]就是进程的环境变量了。
②通过第三方变量environ获取
其实我们写的程序都是子进程,bash才是父进程。而我们在输入指令时,bash会将命令行分散成一个个字符,会将这个字符给指针数组初始化。这样就可以给指令,工具软件等提供命令行选项支持。
而我们写的程序在执行之前,bash也会给main函数里的指针数组初始化。其实main也是一个函数,它也被调用的,至于是谁调用的,这个我们可以认为是操作系统调用的,当调用main函数时,会将自己的环境变量,命令参数什么的给main函数进行初始化。
所以一个程序必须要有两个核心向量表:
- 命令行参数表
- 环境变量表。
我们运行的程序都是子进程,bash才是父进程,bash本身在启动时会从操作系统的配置文件中读取环境变量信息,子进程会继承父进程的环境变量。
这两张表是由操作系统维护的,在程序启动时是操作系统自动初始化的,
所以我们要理解:main函数也是一个被调用的函数,操作系统会将两个表传给main函数的参数进行初始化。
我们可以通过系统调用来获取到环境变量:getenv获取指定的变量。
三、全局属性
环境变量通常具有全局属性,可以被子进程继承下去
因为环境变量是可以被子进程继承下去的。父进程的环境变量可以直接拷贝一份给子进程,也就是子进程继承了父进程的环境变量。所以对应环境变量来说,通常是要具有全局属性。而对于一些普通变量是可以不需要有全局属性的。
直接查看,发现没有结果,说明该环境变量根本不存在
再次运行程序,发现结果有了!说明:环境变量是可以被子进程继承下去的!
四、进程切换
我们要知道操作系统里有很多进程,而CPU只有一个,这就说明多个进程使用一个CPU。那这个是如何实现的呢?
这个操作需要两大核心:
1.进程切换
2.时间片也就是操作系统采用基于进程切换基于时间片轮转的调度算法来使用CPU
【问题1】函数的返回值是如何在外部拿到的呢?
函数的返回值通常是局部变量,函数销毁就没有了,操作系统通常会将这个返回值放入一个CPU寄存器中存着。
【问题2】系统是如何得知我们进程当前执行到哪一行代码呢?
进程中有一个叫程序计数器pc,可以记录当前进程正在执行指令的下一行指令的地址。
【问题3】CPU中存在很多寄存器,这些寄存器扮演着说明角色呢?
1.可以提高效率。
①将进程高频数据放入寄存器中。
②CPU寄存器中保存的是进程相关的数据,这样进程就可以随时随地被CPU快速访问修改了。
2.所以CPU寄存器里保存的是进程的临时数据。而这些临时数据被称为当前进程运行时的上下文。
当时间片结束时,进程从CPU上离开时,要将直接的上下文数据保存好甚至带走(为什么呢?因为该进程可能还没有执行完整,因为时间片的原因而结束,等下次再到这个进程运行时就要从刚刚结束的地方开始运行)而保存数据的目的就是为了下次进程回来切换时,进程原来的数据可以恢复。
所以进程在切换时有两大核心:
- 保存当前进程的上下文,保存在进程的PCB中。
- 恢复将要切换的进程的数据,从进程的PCB中获取。
并发的本质就是很多进程在CPU上以时间片的方式进行来回切换,人整段代码在一定时间内,都得以推进,切换的速度很快CPU执行也很快,时间片一到,首先将当前进程的上下文保存,然后让该进程去等待队列里排队,等将活跃队列运行完,再将轮转队列放上来,这样CPU就可以周而复始的轮转调度了。