目录
一、操作系统的概念、定义,目标
1、操作系统定义:
2、操作系统特征
并发,共享,虚拟,异步
3 实时操作系统编辑
5 中断和异常
中断的处理过程
6 系统调用
系统调用
系统调用与库函数的区别
系统调用的功能
系统调用所涵盖的功能
二 进程管理
1、进程的组成、特征
进程的组成
进程的组织方式
进程(Process)与线程(Thread)的区别:
2 进程的控制
原语:
引起进程切换的事件主要有:
进程切换的步骤:
3、进程管理的五状态模型
3、进程管理
进程间同步的4原则:
进程间同步的方法
线程同步的方法:
4 进程通信
3、作业管理
1、进程调度:
2、什么时候需要进程调度
3、进程调度方式:
4、进程调度的三大机制:
5、进程调度算法:
6、死锁
进程死锁,饥饿、死循环的区别
死锁产生的本质原因:
死锁的四个必要条件
死锁的处理策略:
二、银行家检测算法:
三、死锁的检测和解除:
7、处理机调度
调度算法的评价指标:
4、内存管理
内存的作用:
按照字节编址和按字编址的区别
装入的三种方式:
1、绝对装入:
2、静态重定位(也叫可重定位装入):
3、动态重定位(动态运行时装入)
内存空间
操作系统负责内存的分配与回收
操作系统负责内存空间的分配与回收
操作系统需要提供某种技术从逻辑上对内存空间进行扩充
操作系统负责提供地址转换功能,负责程序的逻辑地址与物理地址的转换
操作系统需要提供内存保护功能,保证各进程在各自的存储空间内运行,互补干扰
覆盖与交换
内存碎片
动态分区算法:首次适应、最佳适应、最坏适应、邻近适应
编辑分页存储管理的 概念
页表:
每个页表项占多少字节:
如何实现地址的转换:
如果访问逻辑地址A
具有块表的地址变换机构
块表(TLB/translation lookaside buffer)
引入快表后,地址的变换过程
局部性原理
两级页表:
分段存储管理方式
分段:
内存分配规则:
页和段的比较:
虚拟内存
请求分页方式
缺页中断机构:
运行机理:
地址变换机构:
页面置换算法:
页面分配策略:
1是系统资源的管理者:处理机管理、存储器管理、文件管理、设备管理
2向上层提供方便易用的服务:联机命令:说一句做一句;脱机命令:说多句做多句
3是最接近硬件的软件
并发:两个或者是多个事件在同一时间间隔内发生,宏观上是同时发生的,但是微观上是交替发生的。
并行:两个或多个事件可以在同一个时刻发生,多核CPU可以实现并行
共享:资源共享,指系统中的资源可供内存中多个并发执行的进程共同使用
虚拟:就是指把一个物理上的实体变为若干个逻辑上对应物
异步:在多道程序环境下,允许程序并发执行,但是由于资源有限,进程的执行不是一贯到底的,而是走走停停,以不可预知的速度向前推进的
中断机制的作用:为了多道批处理系统中让用户进行交互;
中断会使CPU由用户态转变为核心态,使操作系统重新夺回对CPU的控制权
核心态->用户态:执行一个特权指令--修改PSW的标志位为用户态,就代表OS主动让出CPU的使用权
用户态->核心态:由中断引发,触发中断信号意味着OS将强行抢夺CPU的使用权
1、每执行完一个指令后,CPU都需要检查当前是否有外部中断信号
2、如果检查到外部中断信号,则需要保护中断进程的CPU环境(比如程序状态字PSW,程序计数器PC,还有各种通用寄存器),把他们存储在PCB中
3、根据中断信号类型进入相应的中断处理程序
4、恢复原进程的CPU环境并退出中断,返回原程序继续执行
是指OS为应用程序使用的接口
应用程序可以通过系统调用来请求获得操作系统内核的服务
应用程序可以通过系统调用请求操作系统的服务,而文件系统的各种共享资源都必须由操作系统内核同一掌管。所以只要是与共享资源有关的操作(比如存储分配、IO操作、文件管理等),都必须通过系统调用的方式向操作系统内核提出服务请求,由操作系统内核代为完成,可以保证系统的安全与稳定性,防止用户进行非法操作。
设备管理:完成设备的请求释放启动等功能;
文件管理:完成文件的 读写创建删除等功能
进程控制:完成进程创建撤销阻塞唤醒等功能
进程通信:完成进程之间的消息传递/信号传递等功能
内存管理:完成内存的分配回收
系统调用的过程:
1、传参
2、陷入指令
3、由OS内核程序处理系统调用
4、返回应用程序
7 操作系统的体系结构
PCB:
资源分配信息:正在使用的文件,内存区域,IO设备
程序段:程序代码(指令序列)
数据段:运行过程中产生的各种数据(各种变量)
1、链式方式:按照进程状态将PCB分为多个队列,OS持有指向各个队列的指针
2、索引方式:按照进程状态建立索引表,OS持有指向各个索引表的指针
线程:操作系统进行运行调度的最小单位
进程:操作系统进行资源分配的最小单位
区别与联系:
1、进程与线程的区别
进程是OS资源分配的基本单元,线程是处理器任务调度和执行的基本单元。另外的区别还有资源开销,包含关系,内存分配,影响关系,执行过程等;
资源开销:进程有自己独立的代码和数据空间,程序间切换有较大的开销;线程有自己独立的栈和程序计数器(PC),线程之间切换开销小;
包含关系:线程是进程的一部分,一个进程可以包含多个线程
内存分配:同一个进程共享一个进程的地址空间和资源,进程之间的地址空间和资源是独立的
影响关系:一个进程奔溃后,不会对其他进程有影响,但是一个线程奔溃整个进程都会死掉;
https://blog.csdn.net/W546556/article/details/126498560?spm=1001.2014.3001.5501
1、用开/关中断来实现
2、是一种特殊的程序
3、原语的执行必须要一气呵成,不可中断
原语是一种特殊的程序,他的执行具有原子性,也就是说,原语在执行的时候是一气呵成的,不可中断的,一般我们可以用关中断指令,或者开中断指令来实现原子性
CPU在执行了关中断指令以后就不会在例行检查中断信号,直到执行开中断指令之后才会恢复检查
1、当前进程的时间片用完了
2、有优先级更高的进程到达
3、当前进程主动堵塞
4、当前进程终止
1、将运行环境信息(也就是进程上下文)存入PCB
2、PCB移入相关队列
3、选择另一个进程进行执行,并且更新PCB
4、根据PCB恢复新进程所需要的运行环境
创建状态:进程拥有PCB但是其他资源尚未就绪
就绪状态:其他资源(PCB,内存,栈空间,堆空间)都准备好,只差CPU状态
执行状态:获得CPU,程序开始执行
阻塞状态:进程因为某种原因放弃CPU,阻塞以队列的形式放置
终止状态:进程结束由系统清理或者归还PCB状态
临界资源是指一些虽然作为共享资源但是却无法被多个线程同时访问的共享资源,当有进程在使用临界资源时,其他进程必须依据操作系统同步机制等待占用进程释放该共享资源才可重新竞争使用共享资源。
进程同步的作用:协调对竞争资源的使用,让并发执行的多进程之间可以有效的使用
1.使用fork系统调用创建进程:使用fork系统调用无参数,fork会返回两次,分别返回子进程id和0,返回子进程id的是父进程,返回0的是子进程。
2.共享内存:在某种程度上,多进程是共同使用物理内存的,但是由于操作系统的进程管理,进程间的内存空间是独立的,因此进程默认是不能访问进程空间之外的内存空间的。
3.Unix域套接字
域套接字是一种高级的进程间通信的方法,可以用于同一机器进程间通信。
套接字(socket):为网络通信中使用的术语。
Unix系统提供的域套接字提供了网络套接字类似的功能,如Nfinx、uWSGI等。
服务端和客户端分别使用Unix域套接字的过程:
1、互斥锁:互斥锁只有两个状态,加锁和解锁,两个状态可以保证资源访问的串行
2、自旋锁:自旋锁是一种多线程同步的变量,使用自旋锁的线程会反复检查锁变量是否可用,自旋锁的话不会让出CPU,是一种忙等待状态,就是死循环等待锁被释放,自旋锁的效率远高于互斥锁。特点就是避免了进程或者线程的上下文切换的开销,但是不适合在单核CPU使用。
3、读写锁:是一种特殊的自旋锁,允许多个读操作同时访问资源以提高读性能,但是对写操作是互斥的。对于多读少些的操作效率会很高
4、条件变量:允许线程睡眠,直到满足某个条件,再给该线程唤醒;
就是指进程间的信息交换
一个进程不能直接访问另一个进程的地址空间
管道通信:
管道只能采用半双工的方式,某一个时间段之内只能实现单向传输
各进程互斥的访问管道
在管道写满之前不能进行读操作,在管道读完之前不能进行写操作
进程调度是指计算机通过决策筛选决定哪个就绪进程可以获得CPU使用权
1、主动放弃:进程正常终止;运行过程中发生异常而终止;主动阻塞(等待IO);
2、被动放弃:分给进程的时间片用完;有更高优先级的进程进入就绪队列,有更紧急的事情需要处理(比如IO中断)
非抢占式调度: 只能由当前运行的进程主动放弃CPU;
抢占式调度:
就绪队列的排队机制:将就绪进程按照一定的方式排成队列,以便程序可以最快找到进程
选择运行进程的委派机制:调度程序按照某种策略,选择就绪进程,分配CPU资源
新老进程的上下文切换机制:保存当前进程的上下文信息,装入被委派执行进程的运行上下文
1、先来先服务算法:按照在就绪队列中的先后顺序执行
2、短进程优先调度算法:优先选择在就绪队列中估计运行时间最短的进程:会导致饥饿
3、高优先权优先调度算法:进程附带优先权,优先选择优先权重高的进程,可以使得紧急的任务优先执行;
4、时间片轮转调度算法:按照FIFO原则排列就绪进程,每次从队列头部取出待执行进程,分配一个时间片执行,是相对公平的调度算法。
死锁:两个或者两个以上的进程在执行的过程中由于资源争夺而造成的一种阻塞的现象,如果没有外力作用,那么他们将无法推进下去,永远在相互等待;
饥饿:就是长期得不到资源导致进程无法推进
死循环:代码逻辑BUG
1、互斥条件:必须互斥使用资源
2、请求保持条件:进程必须保持一个资源,又提出新的资源需求,新资源被占用,请求被堵塞,被堵塞的进程不释放自己保持的资源;
3、不可剥夺条件:进程获得的资源在未完成使用之前不能被剥夺,只能由进程自身释放
4、环路等待条件:发生死锁时,必然存在一进程资源环形链,环路等待不一定造成死锁,但是死锁一定造成环路等待;
一、预防死锁的办法:破坏四个条件中的一个
1、破环互斥条件:将临界资源改成共享资源;
2、破坏请求和保持条件:系统规定运行之前要一次性申请所有的资源(资源利用率低)
3、破坏不可剥夺条件:当一个进程请求新的资源得不到满足时,必须释放占有资源;(实现复杂,剥夺资源可能会导致部分工作失效,反复申请和释放会造成额外的系统开销)
4、破坏环路等待条件:可以用资源线性排序,申请必须按照递增申请;
检查当前剩余资源能否满足某个线程的最大需求,如果可以,就将该进程加入安全序列,然后等待完成以后,回收资源。
死锁检测算法:为每个进程和资源分配一个号码,然后建立资源分配表和进程等待表
解除:
资源剥夺法:剥夺其他资源给该进程
撤销进程法:撤销死进程
内存用于存放数据;程序在执行之前需要放到内存中才能被CPU处理——缓和CPU与硬盘之间的速度矛盾。
一个地址对应一个地址单元,计算机“按照字节编址”则每个存储单元大小为1字节,就是1B=8个二进制位;
如果字长为16的计算机“按字编址”,那么每个存储单元就是一个字,就是16个二进制位
在编译时如果知道程序将放到内存中的哪个位置,编译程序将产生绝对地址的目标代码。
编译链接以后装入模块的地址都是从0开始的,指令中使用的地址、数据存放的地址都是相对于起始地址而言的逻辑地址。
编译链接后的装入模块的地址都是从0开始的,装入程序把装入模块转入内存后,并不会立即把逻辑地址转换成物理地址,而是要等到程序真正开始执行了才开始。
覆盖是:将程序分为多个段(多个模块)。常用的段常驻内存,不常用的段在需要时调入内存,内存中分为一个固定区和若干个“覆盖区”。需要常驻内存的段放在固定区,调入内存后就不再调出(除非运行结束),不常用的段放在“覆盖区”,需要时调入内存,不用时调出内存。
交换是:内存空间紧张时,系统将内存中某些进程暂时换出外存,把外存中某些已经具备运行条件的进程换入内存,也就是进程在内存和磁盘之间动态调度
暂时换出外存等待的进程处于挂起态
挂起态又可以分为就绪挂起和阻塞挂起
具有对换功能的操作系统中,经常把磁盘空间分为文件区和对换区两部分
文件区:主要用于存放文件,追求存储空间的利用率,因此对于文件区空间的管理采用离散分配方式
对换区只占磁盘空间的一小部分,被换出的进程数据就存放在对换区,对对换区采用连续分配方式,对换区的IO速度比文件区快
内部碎片:分配给某进程的内存区域中,有一些部分没有用上
外部碎片:就是指内存中某一些空闲分区由于太小而难以利用
可以通过紧凑技术来解决外部碎片
为了记录进程每个页面在内存中存放的位置,OS会为每个进程建立一个页表;
一个进程对应一张页表
每个页面对应一个页表项
每个页表项由“页号”和“块号组成
页表记录进程页面和实际存放的内存块之间的映射关系
每个页表项的长度是相同的
假设某系统物理内存大小为4GB,页面大小为4KB,则每个页表项至少应该为多少字节?
内存块大小等于页面大小=4KB=2e12B;
物理内存大小为4GB=2e32
会被分为2e32/2e12=2e20,也就是会需要占用20个位,也就是3个字节表示一个页表项
虽然进程的各个页面是离散存在的,但是在页面内部是连续存放的
1、需要找到逻辑地址A对应的页号P
2、找到P号页面在内存中的起始地址(查页表)
3、确定逻辑地址A的页内偏移量W
逻辑地址A对应的物理地址 = P号页面在内存中的起始地址+页内偏移量W
页号 = 逻辑地址/页面长度(取整数部分)
页内偏移量 = 逻辑地址%页面长度(取余数)
所以可以把逻辑地址拆成(页号 + 页内偏移量)
是一种访问速度很快的高速缓存,用来存放最近访问的页表项的副本,可以加速地址变换的速度;
1、GPU给出逻辑地址,计算页号和页内偏移量,将页号和快表中的所有页号进行比较
2、如果找到匹配的页号,说明要访问的页表项在快表中有副本,就直接在其中取出该页号代表的内存块号,并且与内偏移量拼接形成物理地址,如果快表命中,则访问某个逻辑地址只需要一次访问。
3、如果没有找到匹配的页号,就需要访问内存中的页表,找到对应的页表项,然后将内存块号与页内偏移量拼接形成物理地址,最后,访问该物理地址对应的内存单元。因此,若快表未命中,则访问某个逻辑地址需要两次访存(注意:在找到页表项后,应同时将其存入快表,以便后面 可能再次访问,但若快表已满,则必须按照一定的算法对旧的页表项进行替换)。
时间局部性:如果执行了程序中的某条指令,那么不久后这条指令很有可能再次被执行;如果某个数据被访问过,那么不久之后该数据很可能再次被访问;(因为程序中存在大量循环)
空间局部性:一旦程序访问某个存储单元,在不久之后,其附近的存储单元很有可能会被再次访问(因为很多数据在内存之中是连续存放的)
单级页表存在很多的问题:
按照程序自身的逻辑关系划分为若干个段,每个段都有一个段名,每段从0开始编址
以段为单位进行分配,每个段在内存中占据连续内存,但是在各段之间可以不相邻;
分段系统的逻辑地址结构由段号+段内地址(段内偏移量)
页是信息的物理单位,分页主要是为了实现离散分配,提高内存的利用率,分页对用户不可见
段是信息的逻辑单位,分段是对用户可见的
段页式存储管理:现将逻辑空间按照段式管理分成若干段,再将内存空间按照页式管理分成若干页,分页可以有效提高内存利用率,分段可以更好的满足用户需求。
请求分页存储管理与基本分页存储管理的主要区别:
1、在程序执行的过程中,当访问的信息不在内存时,由OS负责将所需要的信息从外存调入内存,然后继续执行
2、若是内存空间不够,就将内存中暂时用不到的信息换出外存
找到页表项后检查页面是否载入内存,如果没有在内存就会发生缺页中断
缺页中断处理中,需要将缺少的目标页面调入内存,如果有必要还要换出页面
缺页中断属于内中断,属于内中断的故障,即可以被系统修复的异常
找到页表项需要检查页面是否在内存中
若是页面不再内存中,就需要请求调页
若是内存空间不够,还需要换出页面
页面调入内存后,需要修改响应的页表项
1、最佳置换算法(OPT):每次淘汰的页面都是以后不会在使用的或者是最长时间不再使用的
2、先进先出算法(FIFO):每次淘汰的都是最先进入内存的页面
3、最近最久未使用算法(LRU)::每次淘汰的都是最近最久没有使用的
4、时钟置换算法:
5、改进型时钟置换算法
抖动(颠簸)现象:刚刚换出的页面马上又换入内存,刚刚换入内存的页面马上要换出外存,这种频繁的页面调度行为称为抖动,或者是颠簸;