type
status
summary
date
slug
tags
category
icon
password
这里我先补充一下并发的含义是什么:在一个cpu内的多个进程在一段时间内不断切换同时推进完的过程就叫做并发
这种切换就是基于进城切换和基于时间片轮转的调度算法
问题:为什么函数的返回值能被外部拿到,但是里面的形参被销毁了呢?
因为函数的返回值在最后return的时候被传入到了寄存器中,通过cpu寄存器拿到
return a → mov eax 10
问题:系统是如何知道我们执行到哪一行代码了?
通过程序计数器(寄存器)pc,eip:记录当前进程即将执行指令的下一行代码的地址
cpu中有很多的寄存器,用于提高效率,将进程的高频数据放入其中
所以cpu里面的寄存器所储存的数据都是进程相关的数据用于访问和修改数据
进程在进行切换的时候必须经历的两个过程
1.保存上下文
2.恢复上下文
切换下时,将上下文保存,以便在切换上的时候快速的恢复上下文,也就是快速的重新将他放回寄存器中,进程在离开cpu的时候必须要保存上下文数据,甚至是带走,保存的目的都是恢复
环境变量
先来思考一个问题,为什么我们在xhsell上输入命令的时候,操作系统怎么知道这些命令具体是要干什么的呢,为什么我们自己编写有一个代码之后要./才能执行他呢?
其实我们可以试着输入一个命令就是echo $PATH之后会在屏幕上输出很多路径
这里其实就是操作系统在你输入指令后在这些路径下寻找你的指令如果找到了就执行,如果没找到就返回cmd not found
当然我们也能修改这个路径使得系统在查找指令的时候能够找到我们自己写的的命令
执行命令PATH=$PATH:你的路径
这样就能将你的路径添加到环境变量中
我们想要查询环境变量就只能一个一个用echo $查吗?未免太麻烦了,所以这里引入一个新的指令:env(环境英文的简写)这个指令就能将所有的环境变量打印下来
这些等于号前面的就是一些环境变量
在c代码中查看环境变量的方法:stdlib.h头文件中的getenv函数getenv(”PATH”)就能获得环境变量PATH的信息
这里插入一个新的知识点,便于更好的理解环境变量:命令行参数
提问,既然main是一个函数,有返回值,那是谁在调用main函数呢?是一个叫startup的函数调用的,并且main函数也是能有参数的main(int argc,char *argv[])
(在bash命令行解释的时候bash会将你的命令当作一个字符串然后再根据空格拆分为多个字符串然后在执行)
这里main函数的参数其实就是命令行参数,在命令行中输入-a -b选项后在代码中识别不同的选项能看到不同的功能,这就是命令行参数的作用
为指令,工具,软件提供,命令行选项的支持
环境变量具有全局属性:
我们所有运行的进程,都是子进程,在bash启动的时候,会从操作系统中读取环境变量信息,子进程会继承所有的环境变量,所以说环境变量具有全局属性
如何新增一个环境变量:
export MYenvVALUE=1234567890
env |grep MYenvVALUE
这样就能新增加一个环境变量
如何取消一个环境变量呢?
unset MYenvVALUE
这样就能取消一个环境变量了
如果只是这样:MY_VAL=1234567890;
这个就叫本地变量,只在本bash中起作用
在env中查不到
那这里又出现问题了,当我们创建了一个本地变量的时候,在env中查不到也就是不会继承到子进程中,但是我们echo $MY_VAL却能够看到,者到底是为什么呢?
其实这里有两种命令,一种就是创建的子进程还有一种就是内建的一种命令,内建的命令当然就不需要继承就能使用,而这里的echo其实就是bash内建的一种命令
总结一下环境变量:环境变量一般是指操作系统中用来指定操作系统运行环境的一些参数
例如我们在写c++代码的时候,链接的时候从来不知道我们的动态库在哪里,但是照样可以链接成功,生成可执行程序,其中原因就是有环境变量在帮忙查找
而且环境变量通常有特殊作用,并且具有全局性
查看环境变量的方法:
echo $NAME
创建环境变量的方法
export NAME=…
删除环境变量的方法:
unset NAME=…
显示所有环境变量的方法:
env
显示所有环境变量和本地变量的方法:
set
环境变量是能被子进程继承的,通过介绍了命令行参数,来进行证明了继承
(以上全重要部分复习参考:进程地址空间第一节前大半部分
第一座大山的大山:进程地址空间
这个图里面的空间叫做地址空间
这里我们分别区打印这几个空间的地址:
可以发现,这些地址确实是按照最上面是栈,然后是堆,未初始化全局变量,初始化全局变量,然后是常量区,代码段:地址越大,地址越高
这里再引入一个概念就是我们平时学习c语言和c++使用的指针里面的地址都不是物理地址,都是虚拟地址
地址空间
每一个进程都有一个页表,而在页表中,每一个变量都有虚拟地址和一个物理地址,通过虚拟地址能找到物理地址,通过物理地址能访问到该变量的信息,对于父子进程来说,子进程继承可父进程的代码和大部分PCB,同时也大部分继承了页表这样才能通过页表找到代码区的代码从而实现共享代码
但是要做到独立性俺么就不能让子进程中的页表的物理地址指向父进程的地址空间而是要指向他自己的地址空间所以对于子进程的页表来说,虚拟地址不变但是物理地址更改为自己的地址空间地址
所以有一个问题就在这里就解决了为什么说在之前pid一个变量能有两个值:就是因为通过同一个虚拟地址访问但是经过不同的页表不同的映射关系找到的物理地址不同所以访问到的值也不同
什么是进程 =进程的内核数据结构(task_struct&&mm_struct&&页表)mm_struct就是地址空间 + 程序的代码和数据
- Author:PytC
- URL:https://PytC.fun//article/13549b4c-fd33-8042-85fb-fd0d0adc2ced
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!