目录
1.并行与并发
2. 环境变量
2.1 举例子
2.2 命令行参数
2.3 环境变量
1.并行与并发
并行:多个进程在多个CPU下分别、同时运行,称为并行
并发:多个进程在一个CPU下采用进程切换的方式,在一时间段内,多个进程同时推进,称为并发
有这样一个问题
int get_value()
{int x = 42; return x;
}int main()
{int ret = get_value();cout << ret << endl;return 0;
}
为什么函数的返回值,会被外部拿到呢?
通过CPU寄存器,编译器将return x转化成了mov eax 10,eax是CPU中的寄存器,函数直接将x的值放入了寄存器,x自己销毁并不影响这个寄存器,调用方仍可以拿到。
既然进程在一直切换,每个进程就执行时间片的时间,系统如何得知某个进程上次执行到哪行代码了?
有一个程序计数器eip,存储当前执行指令下一条指令的地址。
CPU中有很多寄存器,扮演什么角色?
提高运行效率,进程的高频数据放入寄存器中。因为进程相关的数据需要随时被访问或者修改,所以要放到CPU的寄存器中。
所以CPU寄存器中保存的是进程的临时数据,也就是进程的上下文。进程在从CPU上离开的时候,要将自己的上下文数据保存好,甚至带走,这个保存的目的就是为了恢复。
进程在被切换的时候:保存上下文;进程回来运行时,恢复上下文。
上下文信息就当保存到进程的PCB中,PCB有一个寄存器结构体,专门存每个寄存器中的这些信息
2. 环境变量
直接讲概念有些晦涩,先举几个环境变量出来认识一下。
2.1 举例子
1. 我们想执行自己写的程序就得指明路径:./mycode,那系统怎么知道 ls、pwd 等指令执行时去哪里找呢?怎么知道这些指令程序在哪里呢?
OS在执行命令时,shell会在PATH中的路径下一个一个去找。
PATH:Linux系统的指令搜索路径,以:进行分割
也可以添加其他目录到PATH中,重登Xshell就重置了。
2. 当我们登入时,它怎么知道一上来就在家目录下呢?而不是什么其他的目录呢?
HOME:登入时会执行类似cd &HOME 这样的命令,直接跳到家目录下。
PWD:会记录当前目录的环境变量
有了环境变量的存在,我们的系统就具备了认识用户是谁的能力,只要能认识用户是谁,就能把文件拥有者和权限做对比,从而判断出用户有无读写权限。
2.2 命令行参数
ls是命令,后面的-l就是命令行参数
对这个代码进行下面这样的调用产生了命令行参数类型的结果:
这个程序很好的模拟了命令行参数的实现过程,argv[0]就是命令本身,后面的可变参数列表存储命令行参数。
我们输入的其实是字符串,bash将其打散成 "./mycmd"、"-a"、"b"、"c"。
所以在真正执行main函数之前,操作系统已经干了很多事情了。
为什么要传给main参数呢?为指令、工具、软件等提供命令行选项的支持。
这个代码更能详细的说明命令行参数的作用
可以发现系统自己的命令其实就是类似这么实现的,异曲同工
我们可以发现,main函数也是函数,是操作系统来给它传参,调用它。
2.3 环境变量
但main函数不只这两个参数,还有第三个 env
env代表环境变量表,前面的argv代表命令行参数表
这个程序可以打印出所有环境变量:
我们所运行的进程,都是bash的子进程,bash本身在启动的时候,会从操作系统的配置文件中读取环境变量信息,子进程会继承父进程交给它的环境变量,所以环境变量会被所有子进程继承下去,环境变量具有全局属性!
怎么证明被继承了?
我们自己搞一个环境变量,看看它会不会被继承。
我们可以看到,在命令行中直接定义,在env中是找不到的,这时这个变量叫做本地变量,怎么变成环境变量呢?下一行:export,此时就可以找到我们自己定义的环境变量了。
./mycmd 也是能拿到这个环境变量的
本地变量只会在本bash内有效,不会被继承,而echo是没有创建子进程的,所以echo是能打印这个本地变量的。
这也说明了:命令不一定全都会创建子进程,很有把握的就直接操作了,不用担心会影响bash。
所以命令有两种:
- 常规命令:通过创建子进程去完成的
- 内建命令:bash不创建子进程,而是由自己亲自执行,类似于bash调用了自己写的、或者系统提供的函数(cd 也是典型的内建命令)
取消环境变量:
环境变量就是在操作系统中用来指定操作系统运行环境的一些参数。
int main()
{printf("%S\n", getenv("PATH"));return 0;
}
这样也是可以获得环境变量的