操作系统详述
目录
一、进程管理(这是重点)
1、什么是进程管理
进程管理就是负责CPU的分配,是天然的以时间作为主轴去理解指令的执行。
可以简单的类比我们的日常生活:
6:00——7:00:锻炼;
7:00——7:30:吃早饭;
8:00——12:00:上班;
2、如何做好进程调度
1、需要把进程这个抽象的概念用数据表示处理(抽象成一个对象)——这就是面向对象思想。
变成数据之后,才能被计算机(操作系统)处理。
OS需要管理多个进程,就可以通过List、Map、Queue等数据结构存起来。
class Process/PCB{
//对一个进程对象化的过程
1、关联程序的信息(哪个进程下的哪个程序文件)、
2、关于运行的一些信息
a、进程是那个用户启动的;
b、进程工作目录(PWD:process work directory)
c、什么时候开始、什么时候结束
3、分配的资源有哪些
a、CPU:CPU的占用率(过去的一段时间里,分配给该进程的时间占比)
b、内存:分配给该进程的内存空间(不一定是连续的内存空间)
………………
n、调度时用到的信息
}
2、需要对进程做分区
CPU是比较宝贵的资源,一次只能由一个进程使用,所以此时就要区分开,哪些任务(进程)可以分配CPU,哪些进程暂时不能分配CPU。
通过对进程做状态划分,来区分出于不同情况下的进程
此时就引出了进程状态和进程状态转换这两个个概念:
进程状态
1、新建状态:进程处于正在创建阶段;
2、就绪状态:进程已具备运行条件,但由于没有CPU所以暂时处于不能运行的状态(万事俱备,只欠CPU);
3、运行状态:进程占有CPU,并且在CPU上运行;
4、阻塞(等待)状态:进程因等待某种事件的发生或等待非CPU的其他资源而暂时不能运行的状态(即使CPU空闲,该进程也不能运行);
5、结束状态:进程的所以指令执行结束,但PCB暂时保留,OS还需要做一些其他工作(如资源回收等);
进程状态转换
1、新建→就绪:进程的初始化工作全部完成;
2、就绪→运行:调度程序选择了一个新的进程运行;
3、运行→就绪:运行进程用完了时间片或者一个高优先级进程处于就绪状态,中断正在运行的进程。
4、运行→等待:OS尚未完成服务、对一资源的访问尚不能进行、初始化I/0且必须等待结果或者等待某一进程提供输入。
5、等待→就绪:当所有等待的事件发生时;
6、运行→结束:进程的最后一条指令执行结束;
- 画个图理解一下进程状态转换关系吧(图上的序号就对应上面进程状态转换的序号)
但是,站在OS角度来看,同一时刻处于不同状态下的进程不止一个(除了运行状态),所以OS需要一个数据结构来管理这些进程。
就绪队列:存放所有处于就绪状态的进程(一般只有一个,因为处于就绪状态的进程只差CPU);
阻塞队列:存放所有处于等待状态的进程(一般有很多,每个等待的条件都有一个);
3、现在手上有等待分配CPU的所有进程列表——就绪队列,现在面临的问题是,选择哪个进程上CPU?
要求:要有消息、要保证公平性、要让更紧急的任务被更紧急的处理、低成本解决…
1、先来先服务
2、优先级划分(进程PCB中需要管理一个优先级的属性)
3、短作业优先
………
4、OS什么时候会介入进程调度
需要选择一个新的进程, 进行CPU分配
1.一个新的进程刚处于就绪状态时,当该进程的优先级较高时一具备这种能力的 OS被称为抢占式(实时)
2.运行状态的进程转换为结束状态,此时一个进程结束了
3. OS每隔一段时间,会调度一次 :进程的时间片耗尽
4.进程主动放弃CPU
a.运行->阻塞
b.运行->就绪
5、OS具体怎么进程切换
通过上下文切换——保护上一个进程的上下文+恢复下一个进程的上下文上下文(Context 不是Content)
Context Switch Cs
- 讨论到进程调度中,上下文指的是:以PC寄存器所代表的一组寄存器中的值。
二、内存管理
1.什么是内存管理
操作系统针对不同进程之间进行内存分配的一个功能。
- Java程序员眼中的内存:Java的内存空间分为 栈区堆区、方法区 ……但这些概念是JVM和Java应用之间的概念,操作系统层面是没有这些概念的。JVM只是OS眼中的普通进程,分配给它一些内存,JVM对分配到的内存进行细分,这与操作系统无关。
2.线性(虚拟)地址&&物理地址
- 物理地址:真实的内存中的地址;
- 虚拟地址:物理地址被OS进行转换后的一个地址;
在不同进程中,有可能存在内存地址相同的情况,但实际上是虚拟地址相同,映射到物理地址上一定是不相同的。
画个图看一下吧👇👇👇
那么问题就来了,为什么要有线性地址和物理地址呢? - 在没有线性地址之前的程序世界:同一个程序的多次运行,会产生不同的进程,我们该如何保证同一个进程一定被放到内存的同一个位置呢?这个时候程序员就比较难做了,所以引入线性地址这个概念。
- 引入线性地址这个概念之后,程序员就不用考虑这复杂的问题了,交给MMU(OS的内存管理单元)去处理。
- 此时,OS分配出来的空间只是线性地址空间,实际的物理内存,可以延迟到要访问这段内存时再分配。
举个例子,AB租房子,需要A套房子。B承诺101到200房间给A用(只是分配了线性地址出去)。如果A租下房子后没有使用,则B并不需要真正给A准备100套房子。什么时候A真正需要某个房子了,B再去给A找到房间对应的房号下即可。
然后就引出了进程间通信的问题了……
3、进程通信
理论上,进程之间应该是独立的,但实际上往往是多个进程之间互相配合来完成复杂的工作,所以就有了进程之间交换数据的必要性了。
但是,之前提到过,进程是OS进行资源分配(比如内存)的基本单位,那就意味着,分配给A进程的内存绝对不会分配给B进程,进程A、B之间完全没有了进行数据交换的可能性。所以OS提供了一套机制,用于实现进程之间的数据交换,这也就是进程通信。
进程间通信的常见方式:
1.管道(pipe)——学习linux的时候会接触一些
2.消息队列(message queue)
3.信号量(semaphore)
4.信号(signal)——学习linux的时候会接触一些
5.共享内存(shared memory)
6.网络(network)——workbench和mysqld通信的方式
4、内存管理中主要研究的问题
大家有兴趣的可以自行了解一下,俺在这里就不做过多解释了,毕竟不是很专业🙆♂️
1、管理哪些内存已经被分配,哪些内存暂时未被分配
2、已经分配出去的内存,何时进行回收、如何进行回收
3、物理地址<->线性地址转换
4、内存碎片
……
总结
先说到这里,剩下的俺之后再补充好吧~
拜拜👋