目录
二十、死锁:产生死锁的原因、死锁产生的必要条件、解决死锁的基本方法、预防死锁、避免死锁、解除死锁
一、操作系统的定义
(1)定义:
操作系统(Operating System,简称 OS)是管理计算机硬件与软件资源的程序,是计算机的基石。
操作系统本质上是一个运行在计算机上的软件程序 ,用于管理计算机硬件和软件资源。
操作系统存在屏蔽了硬件层的复杂性。
操作系统的内核(Kernel)是操作系统的核心部分,它负责系统的内存管理,硬件设备的管理,文件系统的管理以及应用程序的管理。 内核是连接应用程序和硬件的桥梁,决定着系统的性能和稳定性。
(2)操作系统的特征:并发性,共享性,虚拟性,异步性
(3)操作系统的功能:处理器管理,存储器管理,设备管理,文件管理,用户接口
二、系统调用、用户态和核心态
(1)核心态:核心态又称管态、系统态,是操作系统管理程序执行时机器所处的状态。它具有较高的特权,能执行包括特权指令的一切指令,能访问所有的寄存器和存储区。
(2)用户态:用户态又称目态,是用户程序执行时机器所处的状态。是具有较低特权的执行状态,它只能执行规定的指令,只能访问指定的寄存器和存储区。
(3)特权指令:只能由操作系统内核部分使用,不允许用户直接使用的指令。如IO指令、设置中断屏蔽指令、清内存指令、存储保护指令、设置时钟指令。
(4)操作系统内核的指令操作工作在核心态:时钟管理、中断机制、原语、系统控制的数据结构及处理。
(5)系统调用:
系统调用是操作系统提供给用户的一种服务,程序设计人员在编写程序的时候可以用来请求操作系统的服务。
由操作系统实现提供的所有系统调用所构成的集合即程序接口或应用编程接口(Application Programming Interface,API)。是应用程序同系统之间的接口。
在我们运行的用户程序中,凡是与系统态级别的资源有关的操作(如文件管理、进程控
制、内存管理等),都必须通过系统调用方式向操作系统提出服务请求,并由操作系统代为完成。
功能:设备管理、文件管理、进程控制、进程通信、内存管理
三、进程和线程的区别,结合JAVA JVM运行时内存
(1)进程是拥有资源的基本单位,线程是独立调度的基本单位
(2)不仅进程之间可以并发,同一进程的多个线程之间也可以并发,使得操作系统有很好的并发性
(3)创建进程或者撤销进程时,系统都要为之分配或回收资源,如内存空间、IO设备等,操作系统所付出的开销远大于创建或撤销线程时的开销。
(4)不同进程地址空间相互独立,同一进程内的线程共享同一地址空间。⼀个进程的线程在另⼀个进程内是不可见的;进程间不会相互影响,而⼀个线程挂掉将可能导致整个进程挂掉
(5)以JAVA虚拟机为例:⼀个进程中可以有多个线程,多个线程共享进程的堆和方法区 (JDK1.8 之后的元空间)资源,但是每个线程有自己的程序计数器、虚拟机栈 和 本地⽅法栈。
四、进程的状态
(1)进程的状态:创建状态、就绪状态、运行状态、阻塞状态、结束状态
(2)进程间的状态转换:就绪-->执行、执行-->阻塞、阻塞-->就绪、执行-->就绪
五、进程间的通信方式
(1)定义:进程通信是指进程之间的信息交换。进程的互斥与同步就是一种进程间的通信方式。由于进程互斥与同步交换的信息量较少且效率较低,因此称这两种通信方式为低级进程通信方式。
(2)通信方式:
1. 管道/匿名管道(Pipes) :它是半双工的,具有固定的读端和写端;它只能用于父子进程或者兄弟进程之间的进程的通信; 它可以看成是⼀种特殊的文件,对于它的读写也可以使用普通的 read、write 等函数。但是它不是普通的文件,并不属于其他任何文件系统,并且只存在于内存中。
2. 有名管道(Names Pipes) : 有名管道严格遵循先进先出(first in first out)。有名管道以磁盘文件的方式存在,可以实现本机任意两个进程通信。有路径名与之相关联,它以一种特殊设备文件形式存在于文件系统中。
3. 信号(Signal) :信号是⼀种比较复杂的通信方式,用于通知接收进程某个事件已经发⽣;
4. 消息队列(Message Queuing) :消息队列存放在内核中,只有在内核重启(即,操作系统重启)或者显示地删除一个消息队列时,该消息队列才会被真正的删除。消息队列克服了信号承载信
息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺。
消息队列,是消息的链接表,存放在内核中。一个消息队列由一个标识符 ID 来标识;消息队列是面向记录的,其中的消息具有特定的格式以及特定的优先级;消息队列独立于发送与接收进程。进程终止时,消息队列及其内容并不会被删除;消息队列可以实现消息的随机查询,消息不一定要以先进先出的次序读取,也可以按消息的类型读取。
5. 信号量(Semaphores) :信号量(semaphore)是一个计数器。用于实现进程间的互斥与同步,而不是用于存储进程间通信数据;信号量用于进程间同步,若要在进程间传递数据需要结合共享内存;信号量基于操作系统的 PV 操作,程序对信号量的操作都是原子操作;每次对信号量的PV 操作不仅限于对信号量值加 1 或减 1,而且可以加减任意正整数;支持信号量组。
6. 共享内存(Shared memory) :使得多个进程可以访问同⼀块内存空间,不同进程可以及时
看到对方进程中对共享内存中数据的更新。这种方式需要依靠某种同步操作,如互斥锁和信号量等。可以说这是最有用的进程间通信方式。
共享内存是最快的一种进程中的通信方式,因为进程是直接对内存进行存取的。
7. 套接字(Sockets) : 此方法主要用于在客户端和服务器之间通过网络进⾏通信。套接字是支
持 TCP/IP 的网络通信的基本操作单元,可以看做是不同主机之间的进程进行双向通信的端点,简单的说就是通信的两⽅的⼀种约定,⽤套接字中的相关函数来完成通信过程。
Java线程的通信方式
volatile
等待/通知机制
join方式
threadLocal
volatile关键字方式
volatile有两大特性,一是可见性,二是有序性,禁止指令重排序,其中可见性就是可以让线程之间进行通信。
volatile语义保证线程可见性有两个原则保证
- 所有volatile修饰的变量一旦被某个线程更改,必须立即刷新到主内存
- 所有volatile修饰的变量在使用之前必须重新读取主内存的值
六、线程间的同步方式
(1)间接相互制约关系(互斥)—— 进程—资源—进程
要求:空闲让进、忙则等待、有限等待、让权等待
(2)直接相互制约关系(同步)—— 进程—进程
(3)临界资源:同时仅允许一个进程使用的资源
(4)临界区:进程中用于访问临界资源的代码
(5)线程间同步的方式:
临界区:当多个线程访问一个独占性共享资源时,可以使用临界区对象。拥有临界区的线程可以访问被保护起来的资源或代码段,其他线程若想访问,则被挂起,直到拥有临界区的线程放弃临界区为止。(临界区只能同一进程中线程使用,不能跨进程使用)。临界区是进程维护的。
以下都是内核对象,操作系统维护。
互斥量(Mutex):采用互斥对象机制,只有拥有互斥对象的线程才有访问公共资源的权限。因为互斥对象只有一个,所以可以保证公共资源不会被多个线程同时访问。比如 Java 中的synchronized 关键词和各种 Lock 都是这种机制。
信号量(Semphares):它允许同一时刻多个线程访问同一资源,但是需要控制同一时刻访
问此资源的最⼤线程数量。
事件(Event):Wait/Notify:通过通知操作的方式来保持多线程同步,还可以方便的实现多线程优先级的比较操作。
七、进程的调度算法
(1)处理器的三级调度:
高级调度——作业调度
中级调度
低级调度——进程调度
(2)进程调度算法:
先来先服务调度算法(FCFS)—— 作业调度、进程调度
短作业优先调度算法(SJF)—— 作业调度、进程调度
优先级调度算法 —— 作业调度、进程调度 —— 非抢占、抢占
时间片轮转调度算法 —— 进程调度
高响应比优先调度算法 —— 作业调度
多级队列调度算法 —— 进程调度
多级反馈队列调度算法 —— 进程调度 —— 多级反馈队列调度算法是时间片轮转调度算法和优先级调度算法的综合与发展
八、内存管理的介绍、常见的几种内存管理机制
(1)功能:内存的分配与回收、地址变换、扩充内存、存储保护
(2)内存保护:
界限寄存器方法:上下界寄存器方法、基址和限长寄存器方法
存储保护键方法
(3)
连续分配管理方式:单一连续分配、固定分区分配、动态分区分配
非连续分配管理方式:基本分页存储管理方式、基本分段存储管理方式、基本段页式存储管理方式(先分段,段内分页)
动态分区分配算法:首次适应算法FF、下次适应算法NF、最佳适应算法BF、最差适应算法WF
九、快表、多级页表
(1)
快表:解决虚拟地址到物理地址的转换速度问题
多级页表:解决虚拟地址空间大,页表也会很大的问题
(2)快表
为了解决虚拟地址到物理地址的转换速度,操作系统在 页表⽅案 基础之上引入了 快表 来加速虚拟地址到物理地址的转换。
我们可以把快表理解为一种特殊的高速缓冲存储器(Cache),其中的内容是页表的一部分或者全部内容。作为页表的 Cache,它的作用与页表相似,但是提⾼了访问速率。由于采⽤页表做地址转换,读写内存数据时 CPU 要访问两次主存。有了快表,有时只要访问一次⾼速缓冲存储器,一次主存,这样可加速查找并提高指令执行速度。
使用快表之后的地址转换流程是这样的:
1. 根据虚拟地址中的页号查快表;
2. 如果该页在快表中,直接从快表中读取相应的物理地址;
3. 如果该页不在快表中,就访问内存中的页表,再从页表中得到物理地址,同时将页表中的该映射表项添加到快表中;
4. 当快表填满后,⼜要登记新页时,就按照⼀定的淘汰策略淘汰掉快表中的⼀个页
(3)多级页表:页表过大,将页表分页存储。
十、分页机制与分段机制
(1)分页机制:
优点:内存利用率高、实现了离散分配、便于存储访问控制、无外部碎片
缺点:需要硬件支持(尤其是快表)、内存访问效率下降、共享困难、内部碎片
(2)分段机制:
优点:便于程序模块化处理和处理变换的数据结构、便于动态链接和共享、无内部碎片
缺点:需要硬件支持、为满足分段的动态增长和减少外部碎片需要拼接技术、分段最大尺寸收到主存可用空间的限制、有外部碎片
(3)相同点:
分页机制和分段机制都是为了提高内存利⽤率。
页和段都是离散存储的,所以两者都是离散分配内存的方式。但是,每个页和段中的内
存是连续的。
(4)不同点:
1. 段是信息的逻辑单位,它是根据用户的需要划分的,为了更好地满足用户的需要,段对用户是可见的 ;页是信息的物理单位,是为了管理主存的方便而划分的,是系统管理所需,为了提高内存利用率,对用户是透明的;
2. 段的大小不固定,由用户编写的程序决定的;页的大小固定,由操作系统决定;
3. 段向用户提供⼆维地址空间(段名+段内位移);页向用户提供的是一维地址空间(给定一个地址即可计算出页号+页内位移);
4. 分段无内部碎片,有外部碎片;分页有内部碎片,无外部碎片。
5. 段是信息的逻辑单位,便于存储保护和信息的共享,页的保护和共享受到限制。分页存储管理系统中将作业的地址空间划分成页面的做法对于用户是透明的,同时作业的地址空间是线性连续的,当系统将作业的地址空间分成大小相同的页面时,被共享的部分不一定包含在一个完整的页面中,这样不应共享的数据也被共享了,不利于保密。另外,共享部分的起始地址在各作业的地址空间划分成页的过程中,在各自页面中的业内位移可能不同,这也使得共享比较难。
十一、逻辑地址和物理地址
(1)逻辑地址:
逻辑地址(Logical Address)是指由程序产生的与段(与页无关,因为只有段对用户可见)相关的偏移地址部分。源代码在经过编译后,目标程序中所用的地址就是逻辑地址,而逻辑地址的范围就是逻辑地址空间。在编译程序对源代码进行编译时,总是从0号单元开始编址,地址空间中的地址都是相对于0开始的,因此逻辑地址也称为相对地址。在系统中运行的多个进程可能会有相同的逻辑地址,但这些逻辑地址映射到物理地址上时就变为了不同的位置。
(2)物理地址:
物理地址(Physical Address)是指出现在CPU外部地址总线上的寻址物理内存的地址信号,是逻辑地址变换后的最终结果地址,物理地址空间是指内存中物理地址单元的集合。进程在运行过程中需要访问存取指令或数据时,都是根据物理地址从主存中取得。物理地址对于一般的用户来说是完全透明的,用户只需要关心程序的逻辑地址就可以了。从逻辑地址到物理地址的转换过程由硬件自动完成,这个转换过程叫作地址重定位。
十二、CPU寻址,虚拟地址空间
(1)CPU寻址:现代处理器使用的是⼀种称为 虚拟寻址(Virtual Addressing) 的寻址方式。使用虚拟寻址,CPU需要将虚拟地址翻译成物理地址,这样才能访问到真实的物理内存。 实际上完成虚拟地址转换为物理地址转换的硬件是 CPU 中含有⼀个被称为 内存管理单元(Memory Management Unit,MMU) 的硬件。
(2)寻址方式:
指令寻址:顺序寻址、跳跃寻址
操作数寻址:隐含寻址、立即寻址、直接寻址、间接寻址、寄存器寻址、寄存器间接寻址、相对寻址、基址寻址、变址寻址
(3)虚拟地址空间:
不适用虚拟地址空间的缺点:用户程序可以访问任意内存,寻址内存的每个字节,对操作系统造成损害。对同时运行多个程序造成困难。
使用虚拟地址空间的优点:
程序可以使用一系列相邻的虚拟地址来访问物理内存中不相邻的大内存缓冲区。
程序可以使用一系列虚拟地址来访问大于可用物理内存的内存缓冲区。当物理内存的供应量变小时,内存管理器会将物理内存页(通常大小为 4 KB)保存到磁盘⽂件。数据或代码页会根据需要在物理内存与磁盘之间移动。
不同进程使用的虚拟地址彼此隔离。一个进程中的代码无法更改正在由另一进程或操作系统使用的物理内存
用户程序只能访问虚拟地址,不会对操作系统造成损害。多个程序可以同时使用相同的虚拟地址同时运行。
十三、虚拟内存
虚拟内存使得应用程序认为它拥有连续的可用的内存(⼀个连续完整的地址空间),而实
际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需
要时进行数据交换。
简单概括:部分装入、请求调入、置换功能、逻辑扩充内存
意义:让程序存在的地址空间与运行时的存储空间分开,程序员可以完全不考虑实际内存的大小,而在地址空间内编写程序。
虚拟存储器的容量由计算机的地址解构决定,并不是无限大。
十四、局部性原理
局部性原理分为时间局部性和空间局部性:
时间局部性 :如果程序中的某条指令一旦执行,不久以后该指令可能再次执行;如果某数据
被访问过,不久以后该数据可能再次被访问。产⽣时间局部性的典型原因,是由于在程序中存在着⼤量的循环操作。
空间局部性 :一旦程序访问了某个存储单元,在不久之后,其附近的存储单元也将被访问,
即程序在一段时间内所访问的地址,可能集中在一定的范围之内,这是因为指令通常是顺序存放、顺序执行的,数据也一般是以向量、数组、表等形式簇聚存储的。
时间局部性是通过将近来使用的指令和数据保存到发哦速缓存存储器中,并使用高速缓存的层次结构实现。空间局部性通常是使用较大的高速缓存,并将预取机制集成到高速缓存控制逻辑中实现。虚拟内存技术实际上就是建立了 “内存⼀外存”的两级存储器的结构,利用局部性原理实现髙
速缓存。
十五、虚拟存储器(=虚拟内存)
基于局部性原理,在程序装入时,可以将程序的一部分装入内存,⽽将其他部分留在外存,就可以启动程序执行。由于外存往往比内存大很多,所以我们运行的软件的内存大小实际上是可以比计算机系统实际的内存大小大的。在程序执行过程中,当所访问的信息不在内存时,由操作系统
将所需要的部分调入内存,然后继续执行程序。另一方面,操作系统将内存中暂时不使用的内容换到外存上,从而腾出空间存放将要调入内存的信息。这样,计算机好像为用户提供了一个比实际内存大的多的存储器——虚拟存储器。
十六、虚拟内存的技术实现
虚拟内存的实现需要建立在离散分配的内存管理方式的基础上。 虚拟内存的实现有以下三种方式:
1. 请求分页存储管理 :建立在分页管理之上,为了支持虚拟存储器功能而增加了 请求调页功能 和 页面置换功能。请求分页是目前最常用的一种实现虚拟存储器的方法。请求分页存储管理系统中,在作业开始运行之前,仅装入当前要执行的部分段即可运行。假如在作业运行的过程中发现要访问的页面不在内存,则由处理器通知操作系统按照对应的页面置换算法将相应的页面调⼊到主存,同时操作系统也可以将暂时不用的页面置换到外存中。
2. 请求分段存储管理 :建⽴在分段存储管理之上,增加了请求调段功能、分段置换功能。请求分段储存管理方式就如同请求分页储存管理方式⼀样,在作业开始运行之前,仅装入当前要执行的部分段即可运行;在执行过程中,可使用请求调入中断动态装入要访问但又不在内存的程序段;当内存空间已满,而又需要装入新的段时,根据置换功能适当调出某个段,以便腾出空间而装⼊新的段。
3. 请求段页式存储管理
硬件和软件支持:
1. ⼀定容量的内存和外存:在载入程序的时候,只需要将程序的⼀部分装入内存,而将其他部分留在外存,然后程序就可以执行了;
十七、页面置换算法
(1)最佳置换算法OPT:每次淘汰以后不再使用或者最迟再被使用的页面
(2)先进先出算法FIFO:每次淘汰先进入内存的页面
(3)最近最少使用算法LRU:选择最近最长时间没有被使用的页面予以淘汰
(4)时钟置换算法CLOCK——最近未使用NRU算法:循环链表遍历,淘汰访问位为0的。(访问位置0)
(5)改进型时钟算法——淘汰:未被访问+未被修改、未被访问+已修改、已访问+未被修改、已访问+已修改(第二圈访问位置0)
(6)最不常用置换算法LFU:淘汰到目前为止访问次数最少的页面,每次发生缺页中断时,淘汰计数值最小的页面,并将所有计数器清零。
(7)页面缓冲算法PBA:PBA算法用FIFO选择被置换页。空闲链表和修改链表。PBA算法是对FIFO算法的发展,通过建立置换页面的缓冲,找回刚被置换的页面,从而减少系统I/O的消耗。PBA算法用FIFO算法选择被置换页,选择出的页面不是立即换出,而是放入两个链表之一中。如果页面未被修改,就将其归入到空闲页面链表的末尾,否则将其归入到已修改页面链表的末尾。这些空闲页面和已修改页面会在内存中停留一段时间。 如果这些页面被再次访问,只需将其从相应链表中移出,就可以返回给进程,从而减少了一次磁盘IO。需要调入新的物理页时,将新页面读入到空闲页面链表的第一个页面中,然后将其从该链表中移出。当已修改页达到一定数目后,再将其一 起写入磁盘,然后将它们归入空闲页面链表。这样能大大减少I/O 操作的次数。
Belady现象:
所谓Belady现象是指:在分页式虚拟存储器管理中,发生缺页时的置换算法采用FIFO(先进先出)算法时,如果对一个进程未分配它所要求的全部页面,有时就会出现分配的页面数增多但缺页率反而提高的异常现象。
例子:1,2,3,4,1,2,5,1,2,3,4,5。一共五页,分配3页帧缺页9次,分配4页帧缺页10次
十八、基本概念:并行,并发,同步,异步,阻塞,非阻塞
十九、为什么有了进程还需要线程
二十、死锁:产生死锁的原因、死锁产生的必要条件、解决死锁的基本方法、预防死锁、避免死锁、解除死锁
(1)死锁:当多个进程因竞争系统资源或相互通信而处于永久阻塞状态时,若无外力作用,这些进程都将无法向前推进。这些进程中的每一个进程,均无限期地等待此组进程中某个其他进程占有的、自己永远无法得到的资源,这种现象称为死锁。
(2)产生死锁的原因:资源竞争、推进顺序不当(系统资源不足、推进顺序不当)系统资源不足是产生死锁的根本原因。
可剥夺资源:虽然资源占有者进程需要使用该资源,但是另一个进程可以强行把该资源从占有者进程处剥夺来归自己使用。
不可剥夺资源:除占有者进程不再需要使用该资源而主动释放资源,其他进程不得在占有者进程使用资源的过程中强行剥夺。
(3)死锁产生的必要条件
互斥条件:进程要求对所分配的资源进行排他性控制,即在一段时间内某种资源仅为一个进程所占有。
不可剥夺条件:进程所获得的资源在未使用完毕之前,不能被其他进程强行夺走,即只能由获得该资源的进程自己来释放。
请求和保持条件:进程每次申请它所需的一部分资源。在等待分配新资源的同时,进程继续占有已经分配到的资源。请求与保持条件也成为部分分配条件。
环路等待条件(循环等待):存在一种进程资源的循环等待链,而链中的每一个进程已经获得的资源同时被链中的下一个进程所请求。
(4)解决死锁的基本方法:鸵鸟算法(忽略死锁)、预防死锁、避免死锁、检测及解除死锁
(5)预防死锁:
破坏互斥条件:允许多个进程同时访问资源。不太可能。
破坏不可剥夺条件:对于一个已经获得了某些资源的进程,若新的资源请求不能立即得到满足,则它必须释放所有自己已经获得的资源,以后需要资源时再重新申请。
破坏请求与保持条件:采用预先静态分配方法。要求进程在其运行之前一次性申请所需要的全部资源,在它的资源为满足之前,不投入运行。一旦投入运行后,这些资源就一直归它所有,也不再提出其他资源请求。
破坏环路等待条件:有序资源分配法。将系统中的所有资源都按类型赋予一个编号,要求每一个进程均严格按照编号递增的次序请求资源,同类资源一次申请完。由于对各种资源编号后不宜修改,从而限制了新设备的增加;不同作业对资源使用的顺序也不完全相同,从而造成了资源浪费;对资源按序使用会增加程序编写的复杂性。
(6)避免死锁:
允许进程动态地申请资源,系统在进行资源分配之前,先计算资源分配地安全性。若此次分配不会导致系统进入不安全状态