五大硬件单元以及典型设备:
-
输入设备:采集获取数据 键盘
-
输出设备:数据输出 显示器
-
存储器:内存 (数据缓存). 硬盘和内存的存储介质是不一样的;内存的存储介质是一种易失性介质:数据断电后丢失。所有设备都是围绕内存工作,内存是中间的数据缓冲带---这种硬件体系结构所带来的软件行为
-
运算器:中央处理器CPU
-
控制器:4+5=中央处理器CPU
硬件结构决定了软件行为:QQ聊天
所有的硬件都是围绕内存工作的
内核:管理计算机上的软硬件资源
应用:为了使计算机更加好用
目的:让计算机更加好用
操作系统如何管理计算机上的软硬件资源:先将被管理者描述出来,将这些描述信息组织起来,通过这个描述信息实现对被管理者的管理。(先描述,再组织来进行管理)
库函数和系统调用接口的关系:库函数封装了系统调用接口
程序:一系列有序的指令集合--就是程序员编写的代码--存储在硬盘中
冯诺依曼--所有的数据指令想要被cpu进行处理,第一步就是将代码和数据加载到内存中
操作系统如何实现多个程序的调度运行:将这个运行中的程序描述起来,然后将这些描述组织起来进行管理
通过实现对PCB的调度管理实现对运行中程序的调度运行--对于操作系统来说这个描述信息-pcb就是进程
-
内存指针能够找到内存中运行的程序代码以及数据
-
上下文数据可以保存程序调度切换时正在处理的数据
-
程序计数器保存进程切换时程序即将执行的下一步指令,等等....通过描述这些信息实现控制一个程序的运行。
操作系统认为现在要运行哪个程序,则找到对应的pcb,将pcb中保存的各种描述信息加载到cpu寄存器上
cpu的分时机制:进程在操作系统中是调度切换运行的,每个进程都有一个CPU时间片(一个进程在CPU上的运行时间段),在CPU上时间片运行完毕后则切换到下一个进程
操作系统该调度哪个进程在cpu上运行,操作系统中有一系列的调度算法
cpu多核--多个处理核心--每个核心都有自己的寄存器,可以调度一个程序的运行
创建了一个新的pcb,然后从父进程pcb中复制了很多数据过来
复制的信息:内存指针,程序计数器,上下文数据......
创建一个子进程出来,跟父进程干的事情是一样的,因为它们的运行的代码以及当前的运行位置都是一样的。
在父进程中返回创建的子进程的pid
在子进程中返回0
理解为什么父子进程运行的代码和位置都一样
理解如何通过返回值进行代码分流
-
pit_t gitpid(void)--返回调用进程的pid--谁调用就返回谁的pid
-
进程的查看:ps -ef / ps-aux
-
进程状态: 就绪/运行/阻塞
-
Linux下进程状态:
-
运行态 R:就绪/运行 (正在运行的以及只要拿到时间片就能运行的). ----运行状态的进程才会被操作系统调度在cpu上运行
-
可中断休眠态 S:当前的阻塞能够被中断唤醒
-
不可中断休眠态 D:当前的阻塞不会被中断唤醒,等待条件满足自己醒来
-
停止态 T :停止运行,什么都不干
-
僵死态 Z: 进程已经退出了,但是资源没有完全释放的一种状态 ---这是一种等待后续处理的状态
子进程先于父进程退出,退出后,为了保存自身的退出原因(返回值),因此资源没有完全释放,但是若父进程没有关注这个退出状态,则子进程虽然退出了,但是资源没有完全释放,处于僵死状态,成为僵尸进程。
处理方法:退出父进程(父进程退出,子进程保存退出原因就没有意义了因此也就被释放了)
为什么要创建一个子进程--子进程干的事情跟父进程是一样的 ---创建子进程可以分摊父进程的工作提高效率
孤儿进程是不会成为僵尸进程的,因为1号进程随时关注子进程退出。
守护进程通常是一种运行在系统后台的批处理(默默的做一些循环反复的事情)程序
守护进程/精灵进程(进程以d结尾):特殊的孤儿进程,脱离终端,会话影响。运行在后台----调研实现
进程状态:Linux下的进程状态/僵尸进程的产生原因,危害,处理和避免/孤儿进程产生以及特性/守护进程
交互式进程:直接与用户进行交互的进程--要求最好能够更加优先的被cpu处理
批处理进程:在后台默默做循环工作的进程
优先级的作用:让操作系统运行的更加合理
CPU密集型程序/io密集型程序
环境变量的好处:使系统运行环境配置更加简单灵活,可以通过设置环境变量给一个进程传递参数信息
查看环境变量:env/set(查看所有变量,包含环境变量) / echo(直接打印某一个环境变量的值)
设置环境变量:export
删除环境变量:unset
$path, 把path当作变量
操作命令:
env:查看所有环境变量,相当于是set子集
echo:打印指定环境变量的内容
set:查看shell中所有变量信息
export:设置一个环境变量,
unset:删除一个变量
MYVAL=1000
export MYVAL
./env | grep MYVAL
环境变量特性:具有继承特性的,子进程默认拥有父进程的环境变量---环境变量也可以用于参数的传递
典型:PATH-系统命令程序的默认搜索路径
1、main函数的第三个参数
int main(int argc,char* argv[],char *env[])--env保存环境变量
2、通过一个全局变量 extern char** environ;--environ保存环境变量 (在本文件中声明有这个变量/然而这个变量的具体内容实际上是外部的,标准库)
3、char *getenv(const char * name)--通过环境变量名称获取一个指定环境变量的数据
地址:对内存单元的编号
指针:指针就是一个存放地址的变量
程序是不占用内存的,运行起来的程序被加载到内存,才会占用内存
一个全局变量,在子进程中修改后打印100,父进程中依然打印1
数据不同,表示肯定没有使用同一块内存空间(一块内存空间不可能存储两个数据) 父子进程打印的数据不同但是地址却是相同的---矛盾
size---表示内存大小
code_start/code_end:描述代码段的起始与结束
为了能够实现不让进程直接访问物理内存
进程直接访问物理内存:
内存地址:内存区域的编号
每个进程都有一个自己的进程地址空间
创建子进程--父子进程代码共享,数据独有
我们在进程中所访问到的地址实际是一个虚拟地址
程序地址空间-->进程地址空间-->虚拟地址空间
虚拟地址空间:通过一个结构体描述出一块完整的连续的线性的地址空间
size/code_start/code_end /data_start/data_end
mm_struct结构体---内存描述符
直接使用物理内存:内存利用率低,缺乏内存访问控制
页表主要功能:映射虚拟地址与物理内存的关系/提供内存访问控制
通过页表映射实现数据在物理内存上的离散式存储,提高了内存利用率
通过页表进行了内存访问控制
每个进程都有自己的虚拟地址空间,因此进程间保证了独立性。
操作系统通过虚拟地址空间向进程描述了一个完整的连续的虚拟地址空间,供进程使用,但是在物理内存中进程数据的存储采用离散式存储(提高内存利用率),并且使用页表映射虚拟地址与物理地址的映射关系,并且在页表中可以实现内存访问控制(标志位表示内存的访问权限)
-
分段式 内存地址的组成:段号+段内偏移 段表(段号-物理段起始地址) 对程序内存管理比较友好 便于程序员/编译器的内存管理(优点)
-
分页式 虚拟地址的构成:页号+页内偏移 提高内存利用率(优点)
-
段页式(先分段,在每一段采用页表) 虚拟地址的构成 段号+段内页号起始+页内偏移+段表+段内页表(在每一个分段内又采用分页式管理)
集合了分页式与分段式的优点(优点)