操作系统(Operating Systems)的定义:操作系统是配置在计算机硬件上的第一层系统软件,它为用户控制和管理着计算机系统中的所有软硬件资源,是计算机系统高效工作;同时又为用户提供良好的用户接口,使用户能够方便、有效、安全地使用计算机资源。
操作系统的特点:(1)高效资源管理;(2)方便用户使用。
操作系统的设计目标:
- 高效性,包括提高系统资源利用率和作业吞吐量;
- 方便性,指得是给用户提供一个方便、高效的操作界面;
- 可扩充性,指得是方便更新或增加新的功能模块;
- 开放性,指得是不同平台上开发的应用程序具有可移植性和可互操作性;
- 安全性,主要包括5个方面:身份认证、访问控制、数据保密性、数据完整性和不可否认性。
操作系统的主要功能:
- 处理机管理功能,主要包括进程控制、进程同步、进程通信、进程调度、线程模型等;
- 内存管理功能,主要包括内存分配、地址映射、内存共享、内存保护和内存扩充等;
- 设备管理功能,主要包括I/O设备的控制、缓冲管理、设备独立性、设备分配、虚拟设备管理和磁盘存储管理;
- 文件管理功能,主要包括文件组织方式、目录管理、文件存储控制、文件共享和保护、文件操作和文件存储空间管理等。
- 用户接口管理功能,主要包括命令行接口、图形用户接口、系统调用接口等。
操作系统的主要特征:
- 并发执行:指两个或多个事件在同一时间间隔内发生。宏观上在一段时间内有多道程序在同时运行,但在单处理器系统中,每一时刻仅有一道程序在执行。微观上各个程序轮流切换地使用CPU,交替执行。
- 资源共享:指计算机系统资源可被内存中存放的多个并发执行进程共同使用。分为互斥型共享、同时型共享。
- 一切皆虚拟:指通过某种管理技术把一个物理实体变为若干个逻辑上的对应物。虚拟技术分为两种:时分复用技术,即将硬件设备(单CPU)的使用时间分割成小的时间片,由于CPU在各个进程之间切换很快,给人感觉是多个CPU在同时执行多个程序;空分复用技术,例如将一个物理存储硬盘虚拟成C、D、E、F多块逻辑硬盘。
- 异步性:即不确定性,指系统中每道程序的推进时间、多道程序间的执行顺序以及完成每道程序所需的时间由于受运行环境的影响都是不确定的、不可预知的。
进程(Process):是程序的一次执行过程,是系统进行处理机调度和资源分配的基本单位。简单来讲,启动了的程序就是进程。但是在引入线程模型的操作系统中,拥有资源的基本单位(进程)和CPU调度的基本单位(线程)就分开处理了。
多进程:为了充分利用CPU,多道程序、交替执行。
进程的三种基本状态:
- 就绪状态,进程只要获得CPU就能立即执行,处于就绪状态的进程可能有多个。
- 执行状态,进程获得CPU并正在运行,在单处理机系统中,多个并发执行的进程中只能有一个进程处于执行状态。
- 阻塞状态,进程需要其他资源或在等待某一事件,处于阻塞状态的进程可能有多个。

进程控制块(PCB):是操作系统为了描述和管理进程而定义的数据结构,记录了进程当前情况以及管理进程所需的全部信息。
- 作用:(1)是进程在系统中存在的唯一标识;(2)保存CPU现场信息,在进程阻塞后再次被调度程序选中时恢复现场使用;(3)提供进程管理所需信息,运行所需的资源信息、程序及数据的地址信息;(4)提供进程调度所需信息,如优先级信息、等待时间等;(5)实现与其他进程的同步和通信。
- 基本内容:(1)进程标识信息,唯一标识一个进程;(2)进程说明信息,包括进程状态、等待原因、进程程序存放位置、进程数据存放位置;(3)处理机状态信息,包括通用寄存器内容、控制寄存器内容、程序状态字寄存器内容;(4)控制信息,进程优先数、队列指针。
- 组织方式:(1)线性方式,无论进程状态如何,将所有PCB连续地存放在内存系统区中;(2)链接方式,将具有相同状态进程的PCB链接成队列,提供执行指针、就绪队列指针、阻塞队列指针和空闲队列指针;(4)索引方式,按照进程的状态分别建立PCB的就绪索引表和阻塞索引表。
进程的控制:
- 进程的创建:主要任务是为进程建立一个进程控制块(PCB),采用fork()系统调用将有关信息填入PCB中,并把它挂入PCB的就绪队列。
- 进程的执行:如果在运行过程中发生了中断或陷入,进程会转入执行操作系统内核程序。中断是激活操作系统的唯一方法,当操作系统获得处理机的控制权后,就可以实现进程切换(只在核心态下发生)。
- 进程阻塞与唤醒:阻塞时,先立即停止该进程的执行;保存现场信息到PCB中,改变状态并将其PCB加入阻塞队列;最后在系统执行调度时,将CPU分配给另一个就绪的进程。当阻塞进程期待的事件发生时,产生中断,操作系统将其唤醒。
- 进程挂起与激活:挂起时,先检查要被挂起的进程状态,从其状态队列中移出;若处于活动就绪状态->改为静止就绪状态,处于活动阻塞状态->改为静止阻塞状态,执行状态->静止就绪;最后调度另一处于活动就绪状态的进程。激活时,先将与激活的挂起进程从外存调入到内存,并且状态改变由静态变为活动,重新将修改状态后的PCB插入到相应队列中。
- 进程撤销:在完成任务后,释放资源、统计相关信息、理顺进程结束后其他相关进程的关系,最后调用进程调度程序选取其他就绪进程获得处理机运行。
进程的局限性:传统操作系统通过进程的并发执行提高了系统资源利用率和作业吞吐量,但进程模型存在如下局限性:
- 每个进程都有一个进程控制块和一个私有的用户地址空间,如果按进程进行并发控制,那么在同一个地址空间中只允许单个执行序列运行。
- 一个进程内部只有一个执行序列,不能满足用户让一个进程内部并发执行多个任务的要求。
- 进程在处理机上的频繁切换给系统造成大量时空开销,这限制了系统中并发执行进程的数目,降低了系统并发执行程序。
- 进程通信代价大。
- 不适合并行计算和分布并行计算的要求。进程之间大量频繁的通信和切换,会大大降低并行度。
线程(Thread):是进程内部一个相对独立的、具有可调度特性的执行单元,是操作系统能够进行运算调度的最小单位。具体而言,线程是进程中的一个实体,是被系统独立调度和分配CPU的基本单位,线程自己基本上不拥有系统资源,只拥有一些在运行中必不可少的资源(如程序计数器、用户栈和核心栈)。同一进程的线程间共享所属进程所拥有的全部资源,每个线程有一个线程控制块(TCB)。
线程的属性:轻型实体,独立调度单位,可并发执行,共享进程资源。
线程的实现:分为内核级线程和用户级线程。
- 用户级线程(ULT),仅存在于用户空间中,与内核无关。就内核而言,它只是管理常规进程,而根本感知不到用户级线程的存在。线程控制块设置在用户空间中,所有对线程的操作也在用户空间中由线程库中的函数(过程)完成。
优缺点:不需要得到内核的支持,线程间切换无须陷入内核,因此线程开销小,速度快;内核以进程为单位进行调度,如果进程中某一个线程阻塞可能导致整个进程阻塞;用户级线程实现方式中,内核每次分派给一个进程只有一个CPU,因此无法让同一进程的多个线程在多个处理机上同时运行。线程切换yield()。 - 内核级线程(KLT),内核根据线程控制块感知内核级线程的存在,并对其进行管理。所有对线程的操作都是通过系统调用由内核中的相应处理程序完成。线程切换schedule()。
优缺点:在多处理器系统中,可使同一进程中的多个线程同时执行,提高了线程的并发执行程度;内核级线程具有很小的数据结构和堆栈,线程切换开销小,切换速度快;但是系统需要频繁进行用户态和核心态的转换,模式切换开销较大。
多线程:一对一模型(每个用户线程设置一个内核级线程与之连接),多对一模型(一个内核级进程管理属于同一进程的多个用户级线程),多对多模型(将n个用户线程映射到m个内核控制线程上,其中要求m<=n)。
线程与进程的区别:
- 调度:线程作为CPU调度的基本单位,真正在处理机上运行的是线程,进程仍然作为拥有资源的基本单位。
- 并发性:一个进程可以有多个线程,并且线程只能在该进程的地址空间内活动。
- 拥有资源:进程是拥有资源的一个独立单位,线程自己不拥有系统资源(只有一些必不可少的资源),同一进程的各个线程共享其所在进程的所有资源。
- 系统开销:操作系统的创建或撤销进程时的开销,将显著地大于创建或撤销线程时的开销。
- 通信:由于同一进程的线程共享该进程的所有资源,所以不须任何特殊措施就能实现数据共享。而进程通信则相当复杂,必须借助诸如通信机制、消息缓冲、管道机制等措施。
- 相似点:与进程类似,线程具有就绪、执行和阻塞3种基本状态,并且随着自身运行和外界环境的变换而不断地在3种状态之间转换。
进程中的多线程共享资源与独享资源的划分:
线程共享资源 | 线程独享资源 |
---|---|
进程代码段 | 线程ID |
进程的公有数据 | 寄存器 |
进程打开的文件描述符 | 线程的堆栈 |
信号的处理器 | 错误返回码 |
进程的当前目录 | 线程的信号屏蔽码 |
进程用户ID与进程组ID | 线程的优先级 |
CPU调度:CPU是计算机中最重要的系统资源,多个并发执行的进程在系统中运行时,必然会竞争CPU,CPU调度就是操作系统对CPU进行合理分配。
进程调度:真正实现了CPU的分配,是操作系统中必须配置的调度。
进程调度的目标:
- 公平性。保证每个进程得到合理的处理机时间和执行速度,不能由于采用某种调度算法而使得某些进程长时间得不到执行,出现“饥饿”现象。
- 高效率。保证处理机的得到充分利用,不让处理机由于空闲等等而浪费大量时间。
- 低响应时间。保证交互命令的及时响应和执行,不能让用户等待过长时间。
- 高吞吐量。单位时间内系统完成的进程数目,会与响应时间矛盾,响应时间小->切换次数多->系统内耗大->吞吐量小。
- 特殊应用要求。
进程调度算法:
- 先来先服务调度算法(FCFS):按照进程就绪的先后顺序调度进程,越早到达的进程,越先执行。
- 短进程优先调度算法(SJF):从就绪队列中选出一个估计运行时间最短的进程,将处理机分配给它,使它立即执行并一直到进程结束。最大限度地降低了平均等待时间,但是长进程在此调度算法中可能长时间得不到运行机会,甚至“饥饿”时间过长而被系统撤销。
- 最短剩余时间优先调度算法(SRTF):采用抢占式调度策略,当新进程加入队列时,需要的运行时间比当前正在运行进程所需的剩余时间短,则执行进程切换。
- 时间片轮转调度算法(RR):将处理机的运行时间划分为等长的时间片,轮转式依次分配给各个就绪进程使用,如果进程在一个时间片内没执行完,那么强行将该进程终止,并将执行状态变为就绪状态。不会出现“饥饿”现象。
- 优先级调度算法(PS):就绪进程按照优先级的顺序排队,调度程序选择优先级最高的进程获得CPU。
- 高响应比优先调度算法(HRRF):R=1+等待时间/需运行时间,既照顾了短作业和长作业,又照顾了先到达程序。缺点是增加了响应比计算的系统开销,导致对实时进程无法做出及时反应。
- 多级反馈队列调度算法(MFQ):综合了时间片轮转调度算法和优先级调度算法,并加以改进得到。目前公认的比较好的一种进程调度算法。
先来先服务 (FCFS) | 时间片轮转 (RR) | 短作业优先 (SJF) | 最短剩余时间 (SRTF) | 优先级 (PS) | 高响应比 (HRRF) | 多级反馈队列 (MFQ) | |
---|---|---|---|---|---|---|---|
调度方式 | 非抢占式 | 抢占式 | 非抢占式 | 抢占式 | 均可 | 均可 | 抢占式 |
吞吐量 | 不突出 | 时间片太小可能变低 | 高 | 高 | 不强调 | 高 | 不突出 |
响应时间 | 可能很高,特别在进程执行时间有很大变化时 | 对于短进程提供良好的响应时间 | 对于短作业提供良好的响应时间 | 提供良好的响应时间 | 提供良好的响应时间 | 提供良好的响应时间 | 不突出 |
系统开销 | 最小 | 低 | 可能高 | 较高 | 较高 | 可能高 | 可能高 |
对进程的作用 | 不利于短进程和I/O繁忙型进程 | 公平对待 | 不利于长进程 | 不利于长进程 | 较好地平衡各种进程 | 良好的均衡 | 可能偏爱I/O繁忙型进程 |
饥饿问题 | 无 | 无 | 可能 | 可能 | 可能 | 无 | 可能 |
进程同步:并发执行的进程因直接制约关系而需相互等待、相互合作,以实现各进程按相互协调的速度向前推进。因间接制约而导致进程交替执行的过程称为进程互斥,进程与进程之间共享临界资源(指某段时间内只允许一个进程使用的资源)。信号量是一种高效的进程同步工具,基本思想是两个或多个进程可以利用彼此间收发的简单信号来实现“正确的”并发执行,一个进程在收到一个指定信号前,会被迫在一个确定的或者需要的地方停下来,从而保持进程间的同步或互斥。
- 生产者-消费者问题:一组生产者进程和一组消费者进程共享一个初始为空、大小为n的缓冲区,只有缓冲区没满时,生产者才能把消息放入到缓冲区,否则必须等待;只有缓冲区不空时,消费者才能从中取出消息,否则必须等待。由于缓冲区是临界资源,它只允许一个生产者放入消息,或者一个消费者从中取出消息。生产者和消费者对缓冲区互斥访问是互斥关系,同时生产者和消费者又是一个相互协作的关系,只有生产者生产之后,消费者才能消费,他们也是同步关系。
- 哲学家就餐问题:五个哲学家,坐在一张圆形餐桌旁,做以下两件事情:吃饭或者思考。吃东西的时候,他们就停止思考,思考的时候也停止吃东西。在圆桌上有五个碗和五支筷子,平时哲学家进行思考,饥饿时便试图取其左、右最靠近他的筷子,只有在他拿到两支筷子时才能进餐,该哲学家进餐完毕后,放下左右两只筷子又继续思考。任一哲学家在自己未拿到两只筷子吃完饭前,不会放下手中已经拿到的筷子,可能会产生死锁问题。
- 读者-写者问题:有读者和写者两组并发进程,共享一个文件,当两个或以上的读进程同时访问共享数据时不会产生副作用(不互斥),但若某个写进程和其他进程(读进程或写进程)同时访问共享数据时则可能导致数据不一致的错误(互斥)。因此,允许多个读者可以同时对文件执行读操作;只允许一个写者往文件中写信息;任一写者在完成写操作之前不允许其他读者或写者工作;写者执行写操作前,应让已有的读者和写者全部退出,可能会发生“饥饿”问题。
死锁:指一组并发执行的进程彼此等待对方释放资源,而在没有得到对方占有的资源之前不释放自己占有的资源,导致彼此都不能向前推进的现象。
死锁的特点:(1)陷入死锁的进程是系统并发进程中的一部分,单个进程不能形成死锁;(2)陷入死锁的进程彼此都在等待对方释放资源,形成一个环形等待链;(3)死锁形成后,在没有外力的干预下,陷入死锁的进程不能自己解除死锁;(4)如不及时解除死锁,死锁进程占有的资源不能被其他进程使用,导致更多进程阻塞。
产生死锁的原因:根本原因是“资源竞争、推进顺序不当”。
- 资源竞争:对于可剥夺资源,由于该进程没有使用完,该类资源也可以被其他进程剥夺使用,所以竞争这类资源不可能出现死锁。例如CPU、内存、磁盘等。对于不可剥夺资源,当系统把这类资源分配给某进程后,不能强行收回,只能在进程使用完后自行释放,然后其他进程才能使用。这类资源如打印机、刻录机、CD-ROM驱动器等。
- 推进顺序不当:并发执行的进程在运行中存在异步性,彼此间相对执行速度不定,存在着多种推进顺序。不可剥夺资源少未必一定产生死锁,死锁在一种很巧合的推进顺序中才会发生。
死锁的处理方法:按照死锁处理的时机划分为4类,死锁发生之前预防死锁、避免死锁、发生死锁后检测死锁、解除死锁。
- 预防死锁,需要破坏死锁产生的必要条件中的一个或几个,代价是降低系统资源利用率和减少系统吞吐量。必要条件包括:(1)互斥条件;(2)请求和保持条件;(3)不剥夺条件;(4)环路等待条件。
- 避免死锁,对进程提出的每一次资源请求进行动态检查,计算较为复杂。银行家算法是一种典型的安全资源分配方法,思想是在资源分配前,资源分配程序计算资源分配后系统是否处于安全状态,如处于安全状态则把资源分配给申请进程,如处于不安全状态则令申请资源的进程阻塞,不响应其资源申请。
- 检测死锁,为了准确识别除陷入死锁的进程和资源,缺点是通过剥夺解除死锁,会给系统或用户造成一定的损失。
- 解除死锁,常用方法是抢占某个进程占有的资源、撤销或挂起一些进程,力争以较低的系统代价解除死锁。
- 鸵鸟算法,据说鸵鸟看到危险动物时就把头埋在沙砾中,装作看不见。在死锁问题上,就是不对死锁采取任何处理方法,因为实际上经过统计,死锁发生的概率是很小的,只有在极偶然的情况下才会出现死锁。
参考书籍:《实用操作系统教程(第2版)》李建伟主编
推荐参考链接:https://zhuanlan.zhihu.com/p/161001143