新泰网站制作公司,佛山外贸网站建设新闻,网站建设托管合同,杭州建设工程网一、计算机系统概述
1.简介 什么是操作系统#xff1f; 操作系统#xff08;Operating Ststem#xff0c; OS#xff09;是指控制和管理整个计算机系统的硬件和软件资源#xff0c;并合理地组织调度计算机的工作和资源的分配#xff0c;以提供给用户和其他软件方便的接口…一、计算机系统概述
1.简介 什么是操作系统 操作系统Operating Ststem OS是指控制和管理整个计算机系统的硬件和软件资源并合理地组织调度计算机的工作和资源的分配以提供给用户和其他软件方便的接口和环境它是计算机系统中最基本的系统软件。 操作系统在系统中的位置 操作系统的功能和目标 1、系统资源的管理者
文件管理内存管理处理机CPU管理设备计算机硬件例如摄像头管理
2、用户和计算机硬件之间的接口 3、对硬件机器的拓展 操作系统的四个特征 并发 并发是指两个或多个事件在同一时间间隔内发生。这些事件在宏观上是同时发生的在微观上是交替发生的。
易混淆的概念——并行两个或多个事件在同一时刻同时发生 共享 共享即资源共享是指系统中的资源内存中多个并发执行的进程共同使用。 所谓的“同时”往往是宏观上的而在微观上这些进程可能是交替地对该资源进行访问的(即分时共享)
生活实例:
互斥共享方式:使用QQ和微信视频。同一时间段内摄像头只能分配给其中一个进程。同时共享方式:使用QQ发送文件A同时使用微信发送文件B。宏观上看两边都在同时读取并发送文件说明两个进程都在访问硬盘资源从中读取数据。微观上看两个进程是交替着访问硬盘的。 虚拟 虚拟是指把一个物理上的实体变为若干个逻辑上的对应物。物理实体前者是实际存在的而逻辑上对应物后者是用户感受到的。 异步 异步是指在多道程序环境下允许多个程序并发执行但由于资源有限进程的执行不是一贯到底的而是走走停停以不可预知的速度向前推进这就是进程的异步性。
只有系统拥有并发性才有可能导致异步性。
2.操作系统的运行机制和体系结构 指令 CPU 程序 操作系统的内核 由于内核划分功能的不同内核分为大内核和微内核。 大内核和微内核的优缺点 类比:
操作系统的体系结构问题与企业的管理问题很相似。内核就是企业的管理层负责一些重要的工作。只有管理层才能执行特权指令普通员工只能执行非特权指令。用户态、核心态之间的切换相当于普通员工和管理层之间的工作交接大内核:企业初创时体量不大管理层的人会负责大部分的事情。优点是效率高;缺点是组织结构混乱难以维护。微内核:随着企业体量越来越大管理层只负责最核心的一些工作。优点是组织结构清晰方便维护;缺点是效率低。
3.中断和异常
1.概念和作用
中断是指计算机运行过程中出现某些意外情况需主机干预时机器能自动停止正在运行的程序并转入处理新情况的程序处理完毕后又返回原被暂停的程序继续运行。
当中断发生时CPU立即进入核心态当中断发生后当前运行的进程暂停运行并由操作系统内核对中断进行处理。对于不同的中断信号会进行不同的处理。有了中断才能实现多道程序并发执行。“用户态→核心态”是通过中断实现的并且中断是唯一途径。“核心态→用户态”的切换是通过执行一个特权指令将程序状态字 PSW的标志位设置为 “用户态”。
2.分类
中断信号的来源来自CPU内部称为内中断外部称为外中断。 4.系统调用
1.含义
“系统调用”是操作系统提供给应用程序程序员/编程人员使用的接口可以理解为一种可供应用程序调用的特殊函数应用程序可以发出系统调用请求来获得操作系统的服务。 2.作用
**应用程序通过系统调用请求操作系统的服务。**系统中的各种共享资源都由操作系统统一掌管因此在用户程序中凡是与资源有关的操作如存储分配、I/o操作、文件管理等都必须通过系统调用的方式向操作系统提出服务请求由操作系统代为完成。这样可以保证系统的稳定性和安全性防止用户进行非法操作。
3.系统调用和库函数的区别
编程语言c,java中里边有很多库函数其实它们不是所有的库函数就是将系统调用封装起来隐藏一些细节使上层进行系统调用更加方便。
4.其他
系统调用发生在用户态对系统调用的处理发生在核心态。执行陷入指令自陷指令或访管指令会处理内中断使处理器CPU从用户态进入核心态。
二、进程管理
1.进程的定义组成组织方式特征
1.进程
程序 就是指令序列
引入多道程序CPU可以并发执行多个程序之后为了方便操作系统进行管理引入了进程进程实体的概念。
PCB程序段数据段三部分构成了进程实体也叫作进程映像。一般情况下我们把进程实体简称为进程。
例如所谓创建进程实质上是创建进程实体中的PCB;而撤销进程实质上是撤销进程实体中的PCB.
PCB是进程存在的唯一标识。 2.进程的组织方式
在一个系统中通常有数十、数百乃至数千个PCB。为了能对他们加以有效的管理应该用适当的方式把这些PCB组织起来。 注: 进程的组成讨论的是一个进程内部由哪些部分构成的问题而进程的组织讨论的是多个进程之间的组织方式问题。
相当于java中的链表和数组。 3.进程的特征 2.进程的状态和转换
1.状态
进程是程序的一次执行。在这个过程中进程的状态会有各种变化。为了方便各个进程的管理操作系统将进程划分为几个状态。 除此之外进程还有两种状态。 2.转换 3.进程控制
1.含义
进程控制就是要实现进程状态转换。
2.实现
**进程控制由原语实现。**所谓原语一般是指由若干条指令组成的程序段用来实现某个特定功能在执行过程中不可被中断。
原语采用 “关中断指令” 和 “开中断指令” 来实现。 注意 原语运行在核心态。 那么原语是如何实现进程状态的转换呢 更新PCB中的信息如修改进程状态标志、将运行环境保存到PCB、从PCB恢复运行环境) a.所有的进程控制原语一定都会修改进程状态标志 b.剥夺当前运行进程的CPU使用权必然需要保存其运行环境 c.某进程开始运行前必然要恢复期运行环境 将PCB插入合适的队列 分配/回收资源 具体实现如图所示 4.进程通信 进程通信就是进程之间的信息交换。 为了保证安全一个进程不能直接访问另一个进程的地址空间。
操作系统提供了三种方法共享存储消息传递管道通信。
1.共享存储 2.管道通信
1.管道只能采用半双工通信某一时间段内只能实现单向的传输。如果要实现双向同时通信则需要设置两个管道。 2.各进程要互斥地访问管道。 3.数据以字符流的形式写入管道当管道写满时写进程的write()系统调用将被阻塞等待读进程将数据取走。当读进程将数据全部取后管道变空此时读进程的read()系统调用将被阻塞。 4.如果没写满就不允许读。如果没读空就不允许写。 5.数据一旦被读出就从管道中被抛弃这就意味着读进程最多只能有一个否则可能会有读错数据的情况。 3.消息传递
进程间的数据交换以格式化的消息为单位。进程通过操作系统提供的“发送消息/接收消息” 两个原语进行数据交换。
类似于Http协议。 5.线程概念和多线程模型
1.概念
有的进程需要同时做很多事例如用QQ来进行聊天发送文件等而传统的进程只能串行执行一系列程序。因此引入“线程”来增加并发度。 可以把线程理解为轻量级的进程。 线程是一个基本的CPU执行单元也是程序执行流的最小单位。 引入线程后进程作为除CPU之外的系统资源的分配单元。 2.线程分类
1、用户级线程
用户级线程由应用程序通过线程库实现。所有的线程管理工作都由应用程序负责包括线程切换)用户级线程中线程切换可以在用户态下即可完成无需操作系统干预。在用户看来是有多个线程。但是在操作系统内核看来并意识不到线程的存在。用户级线程对用户不透明对操作系统透明)可以这样理解“用户级线程”就是“从用户视角看能看到的线程”。
2、内核级线程
内核级线程的管理工作由操作系统内核完成。线程调度、切换等工作都由内核负责因此内核级线程的切换必然需要在核心态下才能完成。可以这样理解“内核级线程”就是“从操作系统内核视角看能看到的线程”。操作系统只“看得见”内核级线程因此只有内核级线程才是处理机分配的单位。
6.多线程模型
1、多对一模型 多对一模型:多个用户及线程映射到一个内核级线程。每个用户进程只对应一个内核级线程。 优点:用户级线程的切换在用户空间即可完成不需要切换到核心态线程管理的系统开销小效率高 缺点:当一个用户级线程被阻塞后整个进程都会被阻塞并发度不高。多个线程不可在多核处理机上并行运行
2、一对一模型 一对一模型:一个用户级线程映射到一个内核级线程。 优点:当一个线程被阻塞后别的线程还可以继续执行并发能力强。多线程可在多核处理机上并行执行。 缺点:一个用户进程会占用多个内核级线程线程切换由操作系统内核完成需要切换到核心态因此线程管理的成本高开销大。
3、多对多模型 多对多模型:n用户级线程映射到m个内核级线程(n m)。每个用户进程对应m个内核级线程。 克服了多对一模型并发度不高的缺点又克服了一对一模型中一个用户进程占用太多内核级线程开销太大的缺点。
7.处理机调度的概念和层次
含义
在多道程序系统中进程的数量往往是多于处理机的个数的这样不可能同时并行地处理各个进程。
处理机调度就是从就绪队列中按照一定的算法选择一个进程并将处理机分配给它运行以实现进程的并发执行。
调度分为三个层次分别为高级调度中级调度初级调度。
1.高级调度 由于内存空间有限有时无法将用户提交的作业全部放入内存因此就需要确定某种规则来决定将作业调入内存的顺序。 高级调度作业调度)。按一定的原则从外存上处于后备队列的作业中挑选一个(或多个作业给他们分配内存等必要资源并建立相应的进程建立PCB)以使它们获得竞争处理机的权利。 高级调度是辅存外存与内存之间的调度。每个作业只调入一次调出一次。作业调入时会建立相应的PCB作业调出时才撤销PCB。高级调度主要是指调入的问题因为只有调入的时机需要操作系统来确定调出的时机必然是作业运行结束才调出。
2.中级调度
引入了虚拟存储技术之后可将暂时不能运行的进程调至外存等待。等它重新具备了运行条件且内存又稍有空闲时再重新调入内存。这么做的目的是为了提高内存利用率和系统吞吐量。暂时调到外存等待的进程状态为挂起状态。值得注意的是PCB并不会一起调到外存而是会常驻内存。PCB中会记录进程数据在外存中的存放位置进程状态等信息操作系统通过内存中的PCB来保持对各个进程的监控、管理。被挂起的进程PCB会被放到的挂起队列中。中级调度内存调度就是要决定将哪个处于挂起状态的进程重新调入内存。一个进程可能会被多次调出、调入内存因此中级调度发生的频率要比高级调度更高。
补充知识进程的七状态模型
暂时被调到外存等待的进程状态称为挂起状态。挂起状态又可以进一步细分为就绪挂起堵塞挂起两种状态。 3.低级调度 低级调度进程调度其主要任务是按照某种方法和策略从就绪队列中选取一个进程将处理机分配给它。 进程调度是操作系统中最基本的一种调度在一般的操作系统中都必须配置进程调度。 进程调度的频率很高一般几十毫秒一次。
4.三种调度的联系和对比 8.进程调度的时机切换过程和方式
1.进程调度的时机 临界资源 一个时间段内只允许一个进程使用的资源。各进程需要互斥的访问临界资源。
临界区访问临界资源的那段代码。
内核程序临界区一般是用来访问某种内核数据结构的比如进程的就绪队列。
2.进程调度的方式 非剥夺调度方式又称非抢占方式。即只允许进程主动放弃处理机。在运行过程中即便有更紧迫的任务到达当前进程依然会继续使用处理机直到该进程终止或主动要求进入阻塞态。 优点实现简单,系统开销小但是无法及时处理紧急任务适合于早期的批处理系统 剥夺调度方式又称抢占方式。当一个进程正在处理机上执行时如果有一个更重要或更紧迫的进程需要使用处理机则立即暂停正在执行的进程将处理机分配给更重要紧迫的那个进程。 优点可以优先处理更紧急的进程也可实现让各进程按时间片轮流执行的功能通过时钟中断。适合于分时操作系统、实时操作系统
3.进程的切换与过程
1、“狭义的进程调度”与“进程切换”的区别: 狭义的进程调度指的是从就绪队列中选中一个要运行的进程。(这个进程可以是刚刚被暂停执行的进程也可能是另一个进程后一种情况就需要进程切换 进程切换是指一个进程让出处理机由另一个进程占用处理机的过程。
2、广义的进程调度包含了选择一个进程和进程切换两个步骤。
进程切换的过程主要完成了: 对原来运行进程各种数据的保存 对新的进程各种数据的恢复(如:程序计数器、程序状态字、各种数据寄存器等处理机现场信息这些信息一般保存在进程控制块)
注意 : 进程切换是有代价的因此如果过于频繁的进行进程调度、切换必然会使整个系统的效率降低使系统大部分时间都花在了进程切换上而真正用于执行进程的时间减少。
9.调度算法的评价指标 CPU利用率 CPU忙碌的时间占总时间的比例。 系统吞吐量单位时间内完成作业的数量。 周转时间是指从作业被提交给系统开始到作业完成为止的时间间隔。 作业周转时间作业完成时的时间-作业提交时间 平均周转时间各作业周转时间之和/作业数
由于在周转时间相同的情况下运行时间不同的作业给用户的感觉是不一样的所以提出了带权周转时间的概念。 等待时间指进程/作业处于等待处理机状态时间之和等待时间越长用户满意度越低。 对于进程来说等待时间就是指进程建立后等待被服务的时间之和在等待I/O完成的期间其实进程也是在被服务的所以不计入等待时间。对于作业来说不仅要考虑建立进程后的等待时间还要加上作业在外存后备队列中等待的时间。 响应时间指从用户提交请求到首次产生响应所用的时间。
10.调度算法1
1.先来先服务FCFSFirst Come First Serve 2.短作业优先SJFShortest Job First 3.高响应比优先HRRNHighest Response Ratio Next 4.三种算法对比 注:这几种算法主要关心对用户的公平性、平均周转时间、平均等待时间等评价系统整体性能的指标但是不关心“响应时间”也并不区分任务的紧急程度因此对于用户来说交互性很糟糕。因此这三种算法一般适合用于早期的批处理系统当然FCFS算法也常结合其他的算法使用在现在也扮演着很重要的角色。而适合用于交互式系统的调度算法将在下个小节介绍…
11.调度算法2
1.时间片轮转调度RRRound-Robin 如果时间片太大使得每个进程都可以在一个时间片内就完成则时间片轮转调度算法退化为先来先服务调度算法并且会增大进程响应时间。因此时间片不能太大。另一方面进程调度、切换是有时间代价的(保存、恢复运行环境)因此如果时间片太小会导致进程切换过于频繁系统会花大量的时间来处理进程切换从而导致实际用于进程执行的时间比例减少。可见时间片也不能太小。一般来说设计时间片要让切换进程的开销占比不超过1%。
2.优先级调度算法 3.多级反馈队列调度算法 通过下边的例子来加深理解 4.总结
比起早期的批处理操作系统来说由于计算机造价大幅降低因此之后出现的交互式操作系统包括分时操作系统、实时操作系统等更注重系统的响应时间、公平性、平衡性等指标。而这几种算法恰好也能较好地满足交互式系统的需求。因此这三种算法适合用于交互式系统。(比如UNIX使用的就是多级反馈队列调度算法)
12.进程同步与进程互斥
1.进程同步 通过进程通信——管道通信的例子来了解什么是进程同步。
读进程和写进程并发地运行由于并发必然导致异步性因此“写数据”和“读数据”两个操作执行的先后顺序是不确定的。而实际应用中又必须按照“写数据→读数据”的顺序来执行的。如何解决这种异步问题就是“进程同步”所讨论的内容。 含义
同步亦称直接制约关系它是指为完成某种任务而建立的两个或多个进程这些进程因为需要在某些位置上协调它们的工作次序而产生的制约关系。进程间的直接制约关系就是源于它们之间的相互合作。
2.进程互斥
我们把一个时间段内只允许一个进程使用的资源称为临界资源。许多物理设备比如摄像头、打印机都属于临界资源。此外还有许多变量、数据、内存缓冲区等都属于临界资源。对临界资源的访问必须互斥地进行。互斥亦称间接制约关系。进程互斥指当一个进程访问某临界资源时另一个想要访问该临界资源的进程必须等待。当前访问临界资源的进程访问结束释放该资源之后另一个进程才能去访问临界资源。 对临界资源的互斥访问可以在逻辑上分为如下四个部分: 为了实现对临界资源的互斥访问同时保证系统整体性能需要遵循以下原则:
空闲让进。临界区空闲时可以允许一个请求进入临界区的进程立即进入临界区;忙则等待。当已有进程进入临界区时其他试图进入临界区的进程必须等待;有限等待。对请求访问的进程应保证能在有限时间内进入临界区保证不会饥饿)让权等待。当进程不能进入临界区时应立即释放处理机防止进程忙等待。
13.进程互斥的软件实现方法
1.单标志法
算法思想:每个进程在访问完临界区后会把使用临界区的权限转交给另一个进程。也就是说每个进程进入临界区的权限只能被另一个进程赋予。
代码实现 解释
turn的初值为0即刚开始只允许0号进程进入临界区。 若P1先上处理机运行则会一直卡在⑤。直到P1的时间片用完发生调度切换 P0上处理机运行。代码①不会卡住P0P0可以正常访问临界区在 P0访问临界区期间即时切换回P1P1依然会卡在⑤。只有P0在退出区将turn改为1后P1才能进入临界区。 因此该算法可以实现“同一时刻最多只允许一个进程访问临界区” turn表示当前允许进入临界区的进程号而只有当前允许进入临界区的进程在访问了临界区之后才会修改turn的值。 也就是说对于临界区的访问一定是按P0→P1→P0→P1→…这样轮流访问。这种必须“轮流访问”带来的问题是如果此时允许进入临界区的进程是P0而P0一直不访问临界区那么虽然此时临界区空闲但是并不允许P1访问。 因此单标志法存在的主要问题是:违背“空闲让进”原则。 2.双标志先检查法
算法思想: 设置一个布尔型数组flag[]数组中各个元素用来标记各进程想进入临界区的意愿比如“flag[0] ture”意味着0号进程 P0现在想要进入临界区。每个进程在进入临界区之前先检查当前有没有别的进程想进入临界区如果没有则把自身对应的标志flag[li]设为true之后开始访问临界区。 若按照①⑤②⑥③⑦…的顺序执行P0和P1将会同时访问临界区。因此双标志先检查法的主要问题是:违反“忙则等待”原则。 原因在于进入区的“检查”和“上锁”两个处理不是一气呵成的。“检查”后“上锁”前可能发生进程切换。
3.双标志后检查法 4.Peterson算法
算法思想: 双标志后检查法中两个进程都争着想进入临界区但是谁也不让谁最后谁都无法进入临界区。Gary L.Peterson想到了一种方法如果双方都争着想进入临界区那可以让进程尝试“孔融让梨”主动让对方先使用临界区。 Peterson算法用软件方法解决了进程互斥问题遵循了空闲让进、忙则等待、有限等待三个原则但是依然未遵循让权等待的原则。 Peterson算法相较于之前三种软件解决方案来说是最好的但依然不够好。
14.进程互斥的硬件实现方法
1.中断屏蔽方法 2.TestAndSet指令 3.Swap指令 15.信号量机制
1.什么是信号量
用户进程可以通过使用操作系统提供的一对原语来对信号量进行操作从而很方便的实现了进程互斥、进程同步。**信号量其实就是一个变量可以是一个整数也可以是更复杂的记录型变量)**可以用一个信号量来表示系统中某种资源的数量比如:系统中只有一台打印机就可以设置一个初值为1的信号量。原语是一种特殊的程序段其执行只能一气呵成不可被中断。原语是由关中断/开中断指令实现的。一对原语: wait(S)原语和 signal(S)原语可以把原语理解为我们自己写的函数函数名分别为 wait和 signal括号里的信号量s其实就是函数调用时传入的一个参数。wait、signal原语常简称为P、V操作来自荷兰语proberen和 verhogen)。因此做题的时候常把wait(S)、 signal(S)两个操作分别写为P(S)、V(S)。
2.整型信号量
用一个整数型的变量作为信号量用来表示系统中某种资源的数量。
与普通整数变量的区别对信号量的操作只有三种初始化P操作V操作。
下面以打印机为例 3.记录型信号量
整型信号量的缺陷是存在“忙等”问题因此人们又提出了“记录型信号量”即用记录型数据结构表示的信号量。 16.用信号量实现进程互斥同步前驱关系
1.信号量机制实现进程互斥 分析并发进程的关键活动划定临界区如:对临界资源打印机的访问就应放在临界区) 设置互斥信号量mutex初值为1 在临界区之前执行P(mutex) 在临界区之后执行V(mutex)
注意 对不同的临界资源如摄像头打印机需要设置不同的互斥信号量。
注意P、V操作必须成对出现。缺少P(mutex)就不能保证临界资源的互斥访问。缺少V(mutex)会导致资源永不被释放等待进程永不被唤醒。
2.信号量机制实现进程同步
进程同步要让各并发进程按要求有序的进行。
那么如何实现呢 分析什么地方需要实现“同步关系”即必须保证“一前一后”执行的两个操作或两句代码) 设置同步信号量s,初始为0 在“前操作”之后执行v(S) 在“后操作”之前执行P(S) 下面通过一个例子来解释要求进程2的代码4必须在进程1的代码2之后执行。 3.信号量机制实现前驱关系
进程P1中有句代码S1P2中有句代码S2 …P… P6中有句代码S6。这些代码要求按如下前驱图所示的顺序来执行: 其实每一对前驱关系都是一个进程同步问题需要保证一前一后的操作)因此
要为每一对前驱关系各设置一个同步变量在“前操作”之后对相应的同步变量执行V操作在“后操作”之前对相应的同步变量执行Р操作 17.生产者——消费者问题
1.问题描述
系统中有一组生产者进程和一组消费者进程生产者进程每次生产一个产品放入缓冲区消费者进程每次从缓冲区中取出一个产品并使用。(注:这里的“产品”理解为某种数据) 生产者、消费者共享一个初始为空、大小为n的缓冲区。 只有缓冲区没满时生产者才能把产品放入缓冲区否则必须等待。 只有缓冲区不空时消费者才能从中取出产品否则必须等待。 缓冲区是临界资源各进程必须互斥地访问。
2.问题分析 3.如何实现 4.能够改变相邻PV的顺序 18.多生产者——多消费者
1.问题描述 桌子上有一只盘子每次只能向其中放入一个水果。爸爸专向盘子中放苹果妈妈专向盘子中放橘子儿子专等着吃盘子中的橘子女儿专等着吃盘子中的苹果。只有盘子空时爸爸或妈妈才可向盘子中放一个水果。仅当盘子中有自己需要的水果时儿子或女儿可以从盘子中取出水果。用PV操作实现上述过程。 2.如何实现 问题可不可以不使用问题信号量
结论:即使不设置专门的互斥变量mutex也不会出现多个进程同时访问盘子的现象。
原因在于:本题中的缓冲区大小为1在任何时刻apple、orange、plate三个同步信号量中最多只有一个是1。因此在任何时刻,最多只有一个进程的P操作不会被阻塞并顺利地进入临界区…
如果盘子缓冲区数量为2可能会出现两个进程同时访问缓冲区的情况有可能导致两个进程写入缓冲区的数据相互覆盖的情况。
3.总结
在生产者-消费者问题中如果缓冲区大小为1那么有可能不需要设置互斥信号量就可以实现互斥访问缓冲区的功能。当然这不是绝对的要具体问题具体分析。建议:在考试中如果来不及仔细分析可以加上互斥信号量保证各进程一定会互斥地访问缓冲区。但需要注意的是实现互斥的P操作一定要在实现同步的P操作之后否则可能引起“死锁”。
19.吸烟者问题
1.问题描述 假设一个系统有三个抽烟者进程和一个供应者进程。每个抽烟者不停地卷烟并抽掉它但是要卷起并抽掉一支烟抽烟者需要有三种材料:烟草、纸和胶水。三个抽烟者中第一个拥有烟草、第二个拥有纸、第三个拥有胶水。供应者进程无限地提供三种材料供应者每次将两种材料放桌子上拥有剩下那种材料的抽烟者卷一根烟并抽掉它并给供应者进程一个信号告诉完成了供应者就会放另外两种材料再桌上这个过程一直重复(让三个抽烟者轮流地抽烟)。 2.如何解决 20.读者——写者问题
1.问题描述
有读者和写者两组并发进程共享一个文件当两个或两个以上的读进程同时访问共享数据时不会产生副作用但若某个写进程和其他进程读进程或写进程同时访问共享数据时则可能导致数据不一致的错误。因此要求:
①允许多个读者可以同时对文件执行读操作;
②只允许一个写者往文件中写信息;
③任一写者在完成写操作之前不允许其他读者或写者工作;
④写者执行写操作前应让已有的读者和写者全部退出。 2.如何实现 潜在的问题只要读进程还在读写进程就要一直堵塞等待可能会饿死。因此在这种算法中读进程优先。下面来实现“ 先来先服务”算法这样就不会导致写进程饿死。 3.总结
读者-写者问题为我们解决复杂的互斥问题提供了一个参考思路。 其核心思想在于设置了一个计数器count用来记录当前正在访问共享文件的读进程数。我们可以用count的值来判断当前进入的进程是否是第一个/最后一个读进程从而做出不同的处理。 另外对count变量的检查和赋值不能一气呵成导致了一些错误如果需要实现“一气呵成”自然应该想到用互斥信号量。 最后还要认真体会我们是如何解决“写进程饥饿”问题的。
21.哲学家吃饭
1.问题描述 一张圆桌上坐着5名哲学家每两个哲学家之间的桌上摆一根筷子桌子的中间是一碗米饭。哲学家们倾注毕生的精力用于思考和进餐哲学家在思考时并不影响他人。只有当哲学家饥饿时才试图拿起左、右两根筷子一根一根地拿起)。如果筷子已在他人手上则需等待。饥饿的哲学家只有同时拿起两根筷子才可以开始进餐当进餐完毕后放下筷子继续思考。 2.问题分析
1.关系分析。系统中有5个哲学家进程5位哲学家与左右邻居对其中间筷子的访问是互斥关系。
2.整理思路。这个问题中只有互斥关系但与之前遇到的问题不同的是每个哲学家进程需要同时持有两个临界资源才能开始吃饭。如何避免临界资源分配不当造成的死锁现象是哲学家问题的精髓。 3.信号量设置。定义互斥信号量数组chopstick[5]{1,1,1,1,1}用于实现对5个筷子的互斥访问。并对哲学家按0~4编号哲学家i左边的筷子编号为i右边的筷子编号为(i1)%5。
3.如何实现
如果使用下图所示的方法则会导致死锁问题。 那么如何解决呢 ①可以对哲学家进程施加一些限制条件比如最多允许四个哲学家同时进餐。这样可以保证至少有一个哲学家是可以拿到左右两只筷子的②要求奇数号哲学家先拿左边的筷子然后再拿右边的筷子而偶数号哲学家刚好相反。用这种方法可以保证如果相邻的两个奇偶号哲学家都想吃饭那么只会有其中一个可以拿起第一只筷子另一个会直接阻塞。这就避免了占有一支后再等待另一只的情况。③仅当一个哲学家左右两支筷子都可用时才允许他抓起筷子。 下面用代码实现第三种方式。
22.管程
1.为什么引入管程
信号量机制存在的问题 : 编写程序困难、易出错。 因此人们想设计一种机制让程序员写程序时不需要再关注复杂的PV操作让写代码更轻松。1973年Brinch Hansen首次在程序设计语言(Pascal)中引入了“管程”成分――一种高级同步机制。
2.管程的定义和基本特征
管程相当于对临界区资源进行抽象而编写的一个类。
管程是一种特殊的软件模块有这些部分组成:
局部于管程的共享数据结构说明; 一个类对该数据结构进行操作的一组过程; 类中的方法对局部于管程的共享数据设置初始值的语句; 类中的变量管程有一个名字。 类名
管程的基本特征:
局部于管程的数据只能被局部于管程的过程所访问; 类中变量有自己的作用范围**一个进程只有通过调用管程内的过程才能进入管程访问共享数据; ** 这种互斥特性是由编译器来实现的。每次仅允许一个进程在管程内执行某个内部过程。
3.java中类似于管程的机制单例模式 23.死锁
1.含义 在并发环境下各进程因竞争资源而造成的一种互相等待对方手里的资源导致各进程都阻塞都无法向前推进的现象就是“死锁“。 发生死锁后若无外力干涉,这些进程都将无法向前推进。
2.死锁饥饿死循环的区别 死锁:各进程互相等待对方手里的资源导致各进程都阻塞无法向前推进的现象。 饥饿:由于长期得不到想要的资源某进程无法向前推进的现象。比如:在短进程优先SPF算法中若有源源不断的短进程到来则长进程将一直得不到处理机从而发生长进程“饥饿”。 死循环:某进程执行过程中一直跳不出某个循环的现象。有时是因为程序逻辑bug 导致的有时是程序员故意设计的。
3.死锁产生的必要条件
产生死锁必须同时满足一下四个条件只要其中任一条件不成立死锁就不会发生。
互斥条件:只有对必须互斥使用的资源的争抢才会导致死锁(如哲学家的筷子、打印机设备。像内存、扬声器这样可以同时让多个进程使用的资源是不会导致死锁的(因为进程不用阻塞等待这种资源。不可剥夺条件:进程所获得的资源在未使用完之前不能由其他进程强行夺走只能主动释放。请求和保持条件:进程已经保持了至少一个资源但又提出了新的资源请求而该资源又被其他进程占有此时请求进程被阻塞但又对自己已有的资源保持不放。循环等待条件:存在一种进程资源的循环等待链链中的每一个进程已获得的资源同时被下一个进程所请求。
注意 : 发生死锁时一定有循环等待 , 但是发生循环等待时未必死锁循环等待是死锁的必要不充分条件)
如果同类资源数大于1则即使有循环等待也未必发生死锁。但如果系统中每类资源都只有一个那循环等待就是死锁的充分必要条件了。
4.什么时候会发生死锁
对系统资源的竞争。各进程对不可剥夺的资源如打印机的竞争可能引起死锁对可剥夺的资源(CPU)的竞争是不会引起死锁的进程推进顺序非法。请求和释放资源的顺序不当也同样会导致死锁。例如并发执行的进程P1、P2分别申请并占有了资源R1、R2之后进程p1又紧接着申请资源R2而进程p2又申请资源R1,两者会因为申请的资源被对方占有而阻塞从而发生死锁。信号量的使用不当也会造成死锁。如生产者-消费者问题中如果实现互斥的P操作在实现同步的P操作之前就有可能导致死锁。(可以把互斥信号量、同步信号量也看做是一种抽象的系统资源)
总之对不可剥夺资源的不合理分配可能导致死锁。
5.死锁的处理策略
预防死锁。破坏死锁产生的四个必要条件中的一个或几个。避免死锁。用某种方法防止系统进入不安全状态从而避免死锁银行家算法)死锁的检测和解除。允许死锁的发生不过操作系统会负责检测出死锁的发生然后采取某种措施解除死锁。
24.预防死锁 25.避免死锁
1.什么是安全序列 所谓安全序列就是指如果系统按照这种序列分配资源则每个进程都能顺利完成。只要能找出一个安全序列系统就是安全状态。当然安全序列可能有多个。如果分配了资源之后系统中找不出任何一个安全序列系统就进入了不安全状态。这就意味着之后可能所有进程都无法顺利的执行下去。当然如果有进程提前归还了一些资源那系统也有可能重新回到安全状态不过我们在分配资源之前总是要考虑到最坏的情况。如果系统处于安全状态就一定不会发生死锁。如果系统进入不安全状态则可能会发生死锁。不安全状态未必就是发生了死锁但发生死锁时一定是在不安全状态)因此可以在资源分配之前预先判断这次分配是否会导致系统进入不安全状态以此决定是否答应资源分配请求。这也是“银行家算法”的核心思想。
2.银行家算法
数据结构:
长度为m的一维数组 Available表示还有多少可用资源nm矩阵Max表示各进程对资源的最大需求数nm矩阵Allocation表示已经给各进程分配了多少资源Max - Allocation Need矩阵表示各进程最多还需要多少资源用长度为m的一位数组Request表示进程此次申请的各种资源数
银行家算法步骤:
①检查此次申请是否超过了之前声明的最大需求数②检查此时系统剩余的可用资源是否还能满足这次请求③试探着分配更改各数据结构④用安全性算法检查此次分配是否会导致系统进入不安全状态
安全性算法步骤:
检查当前的剩余可用资源是否能满足某个进程的最大需求如果可以就把该进程加入安全序列并把该进程持有的资源全部回收。不断重复上述过程看最终是否能让所有进程都加入安全序列。
26.死锁的检测和解除
1.死锁的检测
为了能对系统是否已发生了死锁进行检测必须:
①用某种数据结构来保存资源的请求和分配信息; ②提供一种算法利用上述信息来检测系统是否已进入死锁状态。 如果系统中剩余的可用资源数足够满足进程的需求那么这个进程暂时是不会阻塞的可以顺利地执行下去。如果这个进程执行结束了把资源归还系统就可能使某些正在等待资源的进程被激活并顺利地执行下去。相应的这些被激活的进程执行完了之后又会归还一些资源这样可能又会激活另外一些阻塞的进程. 如果按上述过程分析最终能消除所有边就称这个图是可完全简化的。此时一定没有发生死锁相当于能找到一个安全序列)。 如果最终不能消除所有边那么此时就是发生了死锁。
死锁定理:如果某时刻系统的资源分配图是不可完全简化的那么此时系统死锁。
2.死锁的解除
一旦检测出死锁的发生就应该立即解除死锁。 补充:并不是系统中所有的进程都是死锁状态用死锁检测算法化简资源分配图后还连着边的那些进程就是死锁进程。 解除死锁的主要方法有 :
资源剥夺法。挂起暂时放到外存上某些死锁进程并抢占它的资源将这些资源分配给其他的死锁进程。但是应防止被挂起的进程长时间得不到资源而饥饿。撤销进程法或称终止进程法。强制撤销部分、甚至全部死锁进程并剥夺这些进程的资源。这种方式的优点是实现简单但所付出的代价可能会很大。因为有些进程可能已经运行了很长时间已经接近结束了一旦被终止可谓功亏一篑以后还得从头再来进程回退法。让一个或多个死锁进程回退到足以避免死锁的地步。这就要求系统要记录进程的历史信息设置还原点。
如何选择对哪些进程动手
进程优先级 (优先级低的)已执行多长时间 执行时间短的还要多久能完成 时间长的进行处理进程己经使用了多少资源 资源多的进程是交互式的还是批处理式的 进行批处理的
三、内存管理
1.基础知识
内存是用于存放数据的硬件。程序执行前需要先放到内存中才能被CPU处理。 1、相对地址和绝对地址 编译时产生的指令只关心“相对地址”实际放入内存中时再想办法根据起始位置得到“绝对地址”。 Eg: 编译时只需确定变量x存放的相对地址是100也就是说相对于进程在内存中的起始地址而言的地址。CPU 想要找到x在内存中的实际存放位置只需要用进程的起始地址100即可。
相对地址又称逻辑地址绝对地址又称物理地址。 2、写程序到程序运行 2.内存管理
操作系统对内存进行管理那么要管理哪些内容呢 内存空间的分配和回收 操作系统需要提供某种技术从逻辑上对内存空间进行扩充。 操作系统需要提供地址转换功能负责程序的逻辑地址与物理地址的转换 操作系统需要提供内存保护功能。保证各进程在各自存储空间内运行互不干扰
内存保护可采取两种方法:
方法一:
在CPU中设置一对上、下限寄存器存放进程的上、下限地址。进程的指令要访问某个地址时CPU检查是否越界。 方法二:
采用**重定位寄存器又称基址寄存器和界地址寄存器又称限长寄存器**进行越界检查。重定位寄存器中存放的是进程的起始物理地址。界地址寄存器中存放的是进程的最大逻辑地址。 3.覆盖和交换 1.覆盖技术
覆盖技术的思想 : 将程序分为多个段多个模块。常用的段常驻内存不常用的段在需要时调入内存。 内存中分为一个“固定区”和若干个“覆盖区”。需要常驻内存的段放在“固定区”中调入后就不再调出除非运行结束)不常用的段放在“覆盖区”需要用到时调入内存用不到时调出内存。 必须由程序员声明覆盖结构操作系统完成自动覆盖。**缺点:对用户不透明增加了用户编程负担。**覆盖技术只用于早期的操作系统中现在已成为历史。
2.交换技术
交换对换技术的设计思想: 内存空间紧张时系统将内存中某些进程暂时换出外存把外存中某些已具备运行条件的进程换入内存进程在内存与磁盘间动态调度。之前讲的中级调度内存调度就是为这个服务的。 1.应该在外存磁盘的什么位置保存被换出的进程?
具有对换功能的操作系统中通常把磁盘空间分为文件区和对换区两部分。文件区主要用于存放文件主要追求存储空间的利用率因此对文件区空间的管理采用离散分配方式;对换区空间只占磁盘空间的小部分被换出的进程数据就存放在对换区。由于对换的速度直接影响到系统的整体速度因此对换区空间的管理主要追求换入换出速度因此通常对换区采用连续分配方式学过文件管理章节后即可理解。总之对换区的I/O速度比文件区的更快。
2.什么时候应该交换?
交换通常在许多进程运行且内存吃紧时进行而系统负荷降低就暂停。例如:在发现许多进程运行时经常发生缺页就说明内存紧张此时可以换出一些进程;如果缺页率明显下降就可以暂停换出。
3.应该换出哪些进程?
可优先换出阻塞进程;可换出优先级低的进程;为了防止优先级低的进程在被调入内存后很快又被换出有的系统还会考虑进程在内存的驻留时间…
(注意:PCB会常驻内存不会被换出外存)
4.连续分配管理方式
连续分配指为用户进程分配的必须是一个连续的内存空间。 1.单一连续分配 在单一连续分配方式中内存被分为系统区和用户区。系统区通常位于内存的低地址部分用于存放操作系统相关数据;用户区用于存放用户进程相关数据。 内存中只能有一道用户程序用户程序独占整个用户区空间。 优点: 实现简单 ;无外部碎片;可以采用覆盖技术扩充内存;不一定需要采取内存保护eg:早期的 PC操作系统MS-DOS)。 缺点:只能用于单用户、单任务的操作系统中;有内部碎片;存储器利用率极低。
2.固定分区分配 3.动态分区分配
动态分区分配又称为可变分区分配。这种分配方式不会预先划分内存分区而是在进程装入内存时根据进程的大小动态地建立分区并使分区的大小正好适合进程的需要。因此系统分区的大小和数目是可变的。
使用这种方式的话我们需要考虑以下三个问题。 系统要用什么样的数据结构记录内存的使用情况? 当很多个空闲分区都能满足需求时,应该选择哪个分区进行分配? 使用动态分区算法这个将在下一小节进行详细介绍。 如何进行分区的分配与回收操作? 如何分配 ----------- 使用动态分区算法之后修改数据结构即可。 如何回收------------------------------- 牢记一点即可会把相邻的空闲区域合并为一个。
4.内部碎片和外部碎片
动态分区分配没有内部碎片但是有外部碎片。内部碎片分配给某进程的内存区域中如果有些部分没有用上。外部碎片是指内存中的某些空闲分区由于太小而难以利用。如果内存中空闲空间的总和本来可以满足某进程的要求但由于进程需要的是一整块连续的内存空间因此这些进程“碎片”不能满足进程的需求。可以通过紧凑(拼凑Compaction)技术来解决外部碎片。
5.动态分区分配算法
动态分区分配算法:在动态分区分配方式中当很多个空闲分区都能满足需求时应该选择哪个分区进行分配?
1.首次适应算法
算法思想: 每次都从低地址开始查找找到第一个能满足大小的空闲分区。 如何实现: 空闲分区以地址递增的次序排列。每次分配内存时顺序查找空闲分区链(或空闲分区表找到大小能满足要求的第一个空闲分区。 2.最佳适应算法
算法思想: 由于动态分区分配是一种连续分配方式为各进程分配的空间必须是连续的一整片区域。因此为了保证当“大进程”到来时能有连续的大片空间可以尽可能多地留下大片的空闲区即优先使用更小的空闲区。 如何实现: 空闲分区按容量递增次序链接。每次分配内存时顺序查找空闲分区链(或空闲分区表)找到大小能满足要求的第一个空闲分区。 3.最大适应算法
又称最坏适应算法(Largest Fit) 算法思想: 为了解决最佳适应算法的问题――即留下太多难以利用的小碎片可以在每次分配时优先使用最大的连续空闲区这样分配后剩余的空闲区就不会太小更方便使用。 如何实现: 空闲分区按容量递减次序链接。每次分配内存时顺序查找空闲分区链(或空闲分区表找到大小能满足要求的第一个空闲分区。 4.临近适应算法
算法思想: 首次适应算法每次都从链头开始查找的。这可能会导致低地址部分出现很多小的空闲分区而每次分配查找时都要经过这些分区因此也增加了查找的开销。如果每次都从上次查找结束的位置开始检索就能解决上述问题。 如何实现: 空闲分区以地址递增的顺序排列(可排成一个循环链表。每次分配内存时从上次查找结束的位置开始查找空闲分区链或空闲分区表找到大小能满足要求的第一个空闲分区。 5.四种算法对比 6.基本分页存储管理
连续分配: 为用户进程分配的必须是一个连续的内存空间。
非连续分配: 为用户进程分配的可以是一些分散的内存空间。 基本分页存储管理的思想――把内存分为一个个相等的小分区,再按照分区大小把进程拆分成一个个小部分。
将内存空间分为一个个大小相等的分区比如:每个分区4KB每个分区就是一个“页框”或称“页帧”、“内存块”、“物理块”。每个页框有一个编号即“页框号”(或者“内存块号”、“页帧号”、“物理块号”)页框号从0开始。将用户进程的地址空间也分为与页框大小相等的一个个区域称为“页”或“页面”。每个页面也有一个编号即“页号”页号也是从0开始。 (注:进程的最后一个页面可能没有一个页框那么大。因此页框不能太大否则可能产生过大的内部碎片)操作系统以页框为单位为各个进程分配内存空间。进程的每个页面分别放入一个页框中。也就是说进程的页面与内存的页框有一一对应的关系。
各个页面不必连续存放也不必按先后顺序来可以放到不相邻的各个页框中。
思考 将进程地址空间分页之后操作系统该如何实现逻辑地址到物理地址的转换?
要算出逻辑地址对应的页号要知道该页号对应页面在内存中的起始地址要算出逻辑地址在页面内的“偏移量”物理地址 页面始址页内偏移量
如何计算:
页号逻辑地址/页面长度(取除法的整数部分)页内偏移量 逻辑地址%页面长度取除法的余数部分)页面在内存中的起始位置:操作系统需要用某种数据结构记录进程各个页面的起始位置。
举例: 页号80 / 50 1 页内偏移量80 % 50 30 1号页在内存中存放的起始位置450 思考: 如何知道该页号对应页面在内存中的起始地址?
操作系统为每一个进程创建一个页表? 如何理解每个页表项的长度是相同的页号是“隐含的” 7.基本地址变换机构
基本地址变换机构可以借助进程的页表将逻辑地址转换为物理地址。 通常会在系统中设置一个页表寄存器(PTR存放页表在内存中的起始地址F和页表长度M。进程未执行时页表的始址和页表长度放在进程控制块(PCB中当进程被调度时操作系统内核会把它们放到页表寄存器中。
1、执行流程 2、页表项长度页表长度页面大小 页表长度是指这个页表中总共有几个页表项即总共有多少页。页面大小是指一个页面占多大的存储空间。页表项长度是指每个页表项占多大的存储空间。
3、通过下面这个例子来理解页表项长度
Eg:假设某系统物理内存大小为4GB页面大小为4KB内存总共会被分为2^32/ 212220个内存块因此内存块号的范围应该是0~2^20 - 1。因此至少要20个二进制位才能表示这么多的内存块号因此至少要3个字节才够(每个字节8个二进制位3个字节共24个二进制位)。每个块号用三个字节来表示。 8.具有快表的地址变换机构
1.局部性原理
时间局部性: 如果执行了程序中的某条指令那么不久后这条指令很有可能再次执行;如果某个数据被访问过不久之后该数据很可能再次被访问。(因为程序中存在大量的循环) 空间局部性: 一旦程序访问了某个存储单元在不久之后其附近的存储单元也很有可能被访问。(因为很多数据在内存中都是连续存放的)
上小节介绍的基本地址变换机构中每次要访问一个逻辑地址都需要查询内存中的页表。由于局部性原理可能连续很多次查到的都是同一个页表项。既然如此能否利用这个特性减少访问页表的次数呢?
2.快表
快表又称联想寄存器TLB是一种访问速度比内存快很多的高速缓冲存储器用来存放当前访问的若干页表项以加速地址变换的过程。与此对应内存中的页表常称为慢表。
执行流程 9.两级页表
两级页表的出现主要是为了解决单级页表的问题。那么单级页表有什么问题呢
问题一:页表必须连续存放因此当页表很大时需要占用很多个连续的页框。 问题二:没有必要让整个页表常驻内存因为进程在一段时间内可能只需要访问某几个特定的页面。
1.解决问题一
我们可以回想以下当初是如何解决进程必须连续的问题
我们可以把页表放在不同的页框中再用一个表来记录各个各个子页表所在位置我们把这个表叫做页目录表外层页表顶级页表。 2.解决问题二 3.其他细节
若采用多级页表机制则各级页表的大小不能超过一个页面两级页表的访存次数分析假设没有快表机构
第一次访存:访问内存中的页目录表第二次访存:访问内存中的二级页表第三次访存:访问目标内存单元
N级页表访问一个逻辑地址需要N1次访问内存。
10.基本分段存储管理方式
1.分段
进程的地址空间:按照程序自身的逻辑关系划分为若干个段每个段都有一个段名在低级语言中程序员使用段名来编程)每段从0开始编址。 内存分配规则 : 以段为单位进行分配每个段在内存中占据连续空间但各段之间可以不相邻。 分段系统的逻辑地址结构由段号段名和段内地址段内偏移量所组成。 段号的位数决定了每个进程最多可以分几个段。段内地址位数决定了每个段的最大长度是多少。
2.段表 3.段内寻址 4.分段分页对比
页是信息的物理单位。分页的主要目的是为了实现离散分配提高内存利用率。分页仅仅是系统管理上的需要完全是系统行为对用户是不可见的。段是信息的逻辑单位。分段的主要目的是更好地满足用户需求。一个段通常包含着一组属于一个逻辑模块的信息。分段对用户是可见的用户编程时需要显式地给出段名。页的大小固定且由系统决定。段的长度却不固定决定于用户编写的程序。分页的用户进程地址空间是一维的程序员只需给出一个记忆符即可表示一个地址。分段的用户进程地址空间是二维的程序员在标识一个地址时既要给出段名也要给出段内地址。分段比分页更容易实现信息的共享和保护。
11.段页式管理方式
1.分页分段的优缺点 既然两者都有优缺点那么可不可以把他们结合起来呢答案当然是可以的。如下图所示。 2.段页式管理的逻辑结构 段号的位数决定了每个进程最多可以分几个段页号位数决定了每个段最大有多少页页内偏移量决定了页面大小、内存块大小是多少
3.段内寻址 12.虚拟内存
1.传统存储管理方式的特征和缺点 一次性:作业必须一次性全部装入内存后才能开始运行。这会造成两个问题:①作业很大时不能全部装入内存导致大作业无法运行;②当大量作业要求运行时由于内存无法容纳所有作业因此只有少量作业能运行导致多道程序并发度下降。 驻留性:一旦作业被装入内存就会一直驻留在内存中直至作业运行结束。事实上在一个时间段内只需要访问作业的一小部分数据即可正常运行这就导致了内存中会驻留大量的、暂时用不到的数据浪费了宝贵的内存资源。
2.虚拟内存的定义和特征
基于局部性原理忘记的话可以到第8节查看在程序装入时可以将程序中很快会用到的部分装入内存暂时用不到的部分留在外存就可以让程序开始执行。在程序执行过程中当所访问的信息不在内存时由操作系统负责将所需信息从外存调入内存然后继续执行程序。若内存空间不够由操作系统负责将内存中暂时用不到的信息换出到外存。在操作系统的管理下在用户看来似乎有一个比实际内存大得多的内存这就是虚拟内存。
3.易混知识点
虚拟内存的最大容量是由计算机的地址结构 CPU寻址范围确定的虚拟内存的实际容量 min(内存和外存容量之和CPU寻址范围)如: 某计算机地址结构为32位按字节编址内存大小为512MB外存大小为2GB.则虚拟内存的最大容量为2^32B 4GB 。 虚拟内存的实际容量min (2^32B,512MB2GB) 2GB512MB
4、虚拟内存有一下三个主要特征
多次性:无需在作业运行时一次性全部装入内存而是允许被分成多次调入内存。对换性:在作业运行时无需一直常驻内存而是允许在作业运行过程中将作业换入、换出。虚拟性:从逻辑上扩充了内存的容量使用户看到的内存容量远大于实际的容量。
虚拟内存的实现需要建立在离散分配的内存管理方式基础上。 13.请求分页管理方式
1.页表机制
与基本分页管理相比请求分页管理中为了实现“请求调页”
操作系统需要知道每个页面是否已经调入内存;如果还没调入那么也需要知道该页面在外存中存放的位置。当内存空间不够时要实现“页面置换”操作系统需要通过某些指标来决定到底换出哪个页面;有的页面没有被修改过就不用再浪费时间写回外存。有的页面修改过就需要将外存中的旧数据覆盖因此操作系统也需要记录各个页面是否被修改的信息。
因此页表会增加四个字段来显示上面的信息。 2.缺页中断机制
假设此时要访问逻辑地址 (页号页内偏移量 (01024)
在请求分页系统中每当要访问的页面不在内存时便产生一个缺页中断然后由操作系统的缺页中断处理程序处理中断。
此时缺页的进程阻塞放入阻塞队列调页完成后再将其唤醒放回就绪队列。
如果内存中有空闲块则为进程分配一个空闲块将所缺页面装入该块并修改页表中相应的页表项。
如果内存中没有空闲块则由页面置换算法选择一个页面淘汰若该页面在内存期间被修改过则要将其写回外存。未修改过的页面不用写回外存。
缺页中断是因为当前执行的指令想要访问的目标页面未调入内存而产生的因此属于内中断
一条指令在执行期间可能产生多次缺页中断。(如: copy AtoB即将逻辑地址A中的数据复制到逻辑地址B而A、B属于不同的页面则有可能产生两次中断) 3.地址变换 4.补充知识点
①只有“写指令”才需要修改“修改位”。并且一般来说只需修改快表中的数据只有要将快表项删除时才需要写回内存中的慢表。这样可以减少访存次数。
②和普通的中断处理一样缺页中断处理依然需要保留CPU现场。
③需要用某种“页面置换算法”来决定一个换出页面下节内容)
④换入/换出页面都需要启动慢速的I/o操作可见如果换入/换出太频繁会有很大的开销。
⑤页面调入内存后需要修改慢表同时也需要将表项复制到快表中。
14.页面置换算法
1.最佳置换算法
最佳置换算法OPTOptimal):每次选择淘汰的页面将是以后永不使用或者在最长时间内不再被访问的页面这样可以保证最低的缺页率。
最佳置换算法可以保证最低的缺页率但实际上只有在进程执行的过程中才能知道接下来会访问到的是哪个页面。操作系统无法提前预判页面访问序列。因此最佳置换算法是无法实现的。 2.先进先出置换算法
先进先出置换算法FIFO):每次选择淘汰的页面是最早进入内存的页面
实现方法:把调入内存的页面根据调入的先后顺序排成一个队列需要换出页面时选择队头页面即可。队列的最大长度取决于系统为进程分配了多少个内存块。
Belady异常―—当为进程分配的物理块数增大时缺页次数不减反增的异常现象。
**只有FIFO算法会产生Belady异常。**另外FIFO算法虽然实现简单但是该算法与进程实际运行时的规律不适应因为先进入的页面也有可能最经常被访问。因此算法性能差。 3.最近最久未使用算法
最近最久未使用置换算法LRUleast recently used):每次淘汰的页面是最近最久未使用的页面。
实现方法:赋予每个页面对应的页表项中用访问字段记录该页面自上次被访问以来所经历的时间t。当需要淘汰一个页面时选择现有页面中t值最大的即最近最久未使用的页面。 4.时钟置换算法
最佳置换算法性能最好但无法实现;先进先出置换算法实现简单但算法性能差;最近最久未使用置换算法性能好是最接近OPT算法性能的但是实现起来需要专门的硬件支持算法开销大。
时钟置换算法是一种性能和开销较均衡的算法又称CLOCK算法或最近未用算法(NRUNotRecently Used)。
简单的CLOCK 算法实现方法:为每个页面设置一个访问位再将内存中的页面都通过链接指针链接成一个循环队列。当某页被访问时其访问位置为1。当需要淘汰一个页面时只需检查页的访问位。如果是0就选择该页换出;如果是1则将它置为0暂不换出继续检查下一个页面若第一轮扫描中所有页面都是1则将这些页面的访问位依次置为0后再进行第二轮扫描第二轮扫描中一定会有访问位为0的页面因此简单的CLOCK算法选择一个淘汰页面最多会经过两轮扫描) 5.改进型的时钟置换算法
简单的时钟置换算法仅考虑到一个页面最近是否被访问过。事实上如果被淘汰的页面没有被修改过就不需要执行I/o操作写回外存。只有被淘汰的页面被修改过时才需要写回外存。 因此除了考虑一个页面最近有没有被访问过之外操作系统还应考虑页面有没有被修改过。在其他条件都相同时应优先淘汰没有修改过的页面避免I/o操作。这就是改进型的时钟置换算法的思想。 修改位0表示页面没有被修改过; 修改位1表示页面被修改过。
为方便讨论用**访问位修改位**的形式表示各页面状态。如11)表示一个页面近期被访问过且被修改过。
算法规则: 将所有可能被置换的页面排成一个循环队列 第一轮:从当前位置开始扫描到第一个00的帧用于替换。本轮扫描不修改任何标志位 第二轮:若第一轮扫描失败则重新扫描查找第一个01的帧用于替换。本轮将所有扫描过的帧访问位设为0 第三轮:若第二轮扫描失败则重新扫描查找第一个(00的帧用于替换。本轮扫描不修改任何标志位 第四轮:若第三轮扫描失败则重新扫描查找第一个01的帧用于替换。 由于第二轮已将所有帧的访问位设为0因此经过第三轮、第四轮扫描一定会有一个帧被选中因此改进型CLOCK置换算法选择一个淘汰页面最多会进行四轮扫描 6.五种算法对比 15.页面分配策略
1.页面分配置换策略
驻留集:指请求分页存储管理中给进程分配的物理块的集合。
在采用了虚拟存储技术的系统中驻留集大小一般小于进程的总大小。 若驻留集太小会导致缺页频繁系统要花大量的时间来处理缺页实际上用于进程推进的时间很少。 驻留集太大又会导致多道程序并发度下降资源利用率降低。所以应该选择一个合适的驻留集大小。 固定分配:操作系统为每个进程分配一组固定数目的物理块在进程运行期间大小不变。即驻留集大小不变。 可变分配:先为每个进程分配一定数目的物理块在进程运行期间可根据情况做适当的增加或减少。即驻留集大小可变 局部置换:发生缺页时只能选进程自己的物理块进行置换。 全局置换:可以将操作系统保留的空闲物理块分配给缺页进程也可以将别的进程持有的物理块置换到外存再分配给缺页进程。 下面来分别介绍这几种方式。
固定分配局部置换:系统为每个进程分配一定数量的物理块在整个运行期间都不改变。若进程在运行中发生缺页则只能从该进程在内存中的页面中选出一页换出然后再调入需要的页面。这种策略的缺点是:很难在刚开始就确定应为每个进程分配多少个物理块才算合理。(采用这种策略的系统可以根据进程大小、优先级、或是根据程序员给出的参数来确定为一个进程分配的内存块数)可变分配全局置换:刚开始会为每个进程分配一定数量的物理块。操作系统会保持一个空闲物理块队列。当某进程发生缺页时从空闲物理块中取出一块分配给该进程;若已无空闲物理块则可选择一个未锁定的页面换出外存再将该物理块分配给缺页的进程。采用这种策略时只要某进程发生缺页都将获的物理块仅当空闲物理块用完时系统才选择一个未锁定的页面调出。被选择调出的页可能是进程中任意一个进程的页因此被选中的这个进程物理块会减少缺页率会增加。可变分配局部置换 刚开始会为每个进程分配一定数量的物理块当某进程发生缺页时只允许从该进程自己的物理块中选出一个换出外存。如果进程在运行中频繁地缺页系统会为该进程多分配几个物理块直至该进程缺页率趋势适当反之如果进程在运行中缺页率特别低则可适当减少分配给该进程的物理块。
可变分配全局置换:只要缺页就给分配新物理块可变分配局部置换:要根据发生缺页的频率来动态地增加或减少进程的物理块
2.何时调入页面
1预调页策略:根据局部性原理主要是空间局部性一次调入若干个相邻的页面可能比一次调入一个页面更高效。但如果提前调入的页面中大多数都没被访问过则又是低效的。因此可以预测不久之后可能访问到的页面将它们预先调入内存但目前预测成功率只有50%左右。故这种策略主要用于进程的首次调入由程序员指出应该先调入哪些部分。它是运行前调入。
2请求调页策略:进程在运行期间发现缺页时才将所缺页面调入内存。由这种策略调入的页面一定会被访问到但由于每次只能调入一页而每次调页都要磁盘l/o操作因此I/o开销较大。它是运行时调入。
3.从何处调入页面 系统拥有足够的对换区空间:页面的调入、调出都是在内存与对换区之间进行这样可以保证页面的调入、调出速度很快。在进程运行前需将进程相关的数据从文件区复制到对换区。 系统缺少足够的对换区空间:凡是不会被修改的数据都直接从文件区调入由于这些页面不会被修改因此换出时不必写回磁盘下次需要时再从文件区调入即可。对于可能被修改的部分换出时需写回磁盘对换区下次需要时再从对换区调入。 UNIX方式:运行之前进程有关的数据全部放在文件区故未使用过的页面都可从文件区调入。若被使用过的页面需要换出则写回对换区下次需要时从对换区调入。
4.抖动颠簸现象工作集
刚刚换出的页面马上又要换入内存刚刚换入的页面马上又要换出外存这种频繁的页面调度行为称为抖动或颠簸。产生抖动的主要原因是进程频繁访问的页面数目高于可用的物理块数分配给进程的物理块不够)。
为进程分配的物理块太少会使进程发生抖动现象。为进程分配的物理块太多又会降低系统整体的并发度降低某些资源的利用率。
为了研究为应该为每个进程分配多少个物理块Denning提出了进程“工作集”的概念。 驻留集:指请求分页存储管理中给进程分配的内存块的集合。 工作集:指在某段时间间隔里进程实际访问页面的集合。
一般来说驻留集大小不能小于工作集大小否则进程运行过程中将频繁缺页。 四、文件系统
1.文件管理
1、文件――就是一组有意义的信息/数据集合。
2、一个文件有哪些属性
文件名:由创建文件的用户决定文件名主要是为了方便用户找到文件同一目录下不允许有重名文件。标识符:一个系统内的各文件标识符唯一对用户来说毫无可读性因此标识符只是操作系统用于区分各个文件的一种内部名称。类型:指明文件的类型位置:文件存放的路径让用户使用)、在外存中的地址(操作系统使用对用户不可见)大小:指明文件大小创建时间、上次修改时间文件所有者信息保护信息:对文件进行保护的访问控制信息
3、文件分为有结构文件和无结构文件 4、操作系统向上用户和应用程序提供的功能 2.文件的逻辑结构 按文件是否有结构分类可以分为无结构文件、有结构文件两种。
无结构文件:文件内部的数据就是一系列二进制流或字符流组成。又称“流式文件”。如:Windows操作系统中的.txt文件。有结构文件:由一组相似的记录组成又称“记录式文件”。每条记录又若干个数据项组成。如:数据库表文件。一般来说每条记录有一个数据项可作为关键字作为识别不同记录的ID)
我们主要研究有结构文件 1.顺序文件
顺序文件:文件中的记录一个接一个地顺序排列逻辑上记录可以是定长的或可变长的。各个记录在物理上可以顺序存储相当于数组或链式存储相当于链表。
顺序存储又可以分为串结构和顺序结构。 那么这几种存储方式可以快速找到第i个记录对应的地址呢 结论:定长记录的顺序文件若物理上采用顺序存储则可实现随机存取;若能再保证记录的顺序结构则可实现快速检索(即根据关键字快速找到对应记录)
2.索引文件
思考对于可变长记录文件要找到第i个记录必须先顺序第查找前i-1个记录,但是很多应用场景中又必须使用可变长记录。如何解决这个问题?
这时我们可以建立一张索引表来快速找到第i个记录。如图所示 **索引表本身是定长记录的顺序文件。**因此可以快速找到第i个记录对应的索引项。
可将关键字作为索引号内容若按关键字顺序排列则还可以支持按照关键字折半查找。
每当要增加/删除一个记录时需要对索引表进行修改。由于索引文件有很快的检索速度因此主要用于对信息处理的及时性要求比较高的场合。
另外可以用不同的数据项建立多个索引表。如:学生信息表中可用关键字“学号”建立一张索引表。也可用“姓名”建立一张索引表。这样就可以根据“姓名”快速地检索文件了。(Eg: SQL就支持根据某个数据项建立索引的功能)
3.索引顺序文件
思考索引文件的缺点:每个记录对应一个索引表项因此索引表可能会很大。比如:文件的每个记录平均只占8字节而每个索引表项占32个字节那么索引表都要比文件内容本身大4倍这样对存储空间的利用率就太低了。
那么如何解决呢
我们可以建立一个索引顺序文件。
索引顺序文件是索引文件和顺序文件思想的结合。索引顺序文件中同样会为文件建立一张索引表但不同的是:并不是每个记录对应一个索引表项而是一组记录对应一个索引表项。
在本例中学生记录按照学生姓名的开头字母进行分组。每个分组就是一个顺序文件分组内的记录不需要按关键字排序。 4.多级索引顺序文件
为了进一步提高检索效率可以为顺序文件建立多级索引表。
例如对于一个含10^6个记录的文件可先为该文件建立一张低级索引表每100个记录为一组故低级索引表中共有10000个表项(即10000个定长记录)再把这10000个定长记录分组每组100个为其建立顶级索引表故顶级索引表中共有100个表项。 3.文件目录 目录本身就是一种有结构文件由一条条记录组成。每条记录对应一个在该放在该目录下的文件。如图所示 1.文件控制块FCB
目录文件中的一条记录就是一个“文件控制块FCB)。
FCB的有序集合称为“文件目录”一个FCB就是一个文件目录项。
FCB中包含了文件的基本信息文件名、物理地址、逻辑结构、物理结构等存取控制信息是否可读/可写、禁止访问的用户名单等)使用信息如文件的建立时间、修改时间等。
最重要最基本的还是文件名、文件存放的物理地址。
2.单级目录结构 3.二级目录结构 4.多级目录结构树形目录结构 树形目录结构可以很方便地对文件进行分类层次结构清晰也能够更有效地进行文件的管理和保护。但是树形结构不便于实现文件的共享。为此提出了“无环图目录结构”。
5.无环图目录结构 可以用不同的文件名指向同一个文件甚至可以指向同一个目录(共享同一目录下的所有内容。
需要为每个共享结点设置一个共享计数器用于记录此时有多少个地方在共享该结点。用户提出删除结点的请求时只是删除该用户的FCB、并使共享计数器减1并不会直接删除共享结点。
只有共享计数器减为0时才删除结点。
注意:共享文件不同于复制文件。在共享文件中由于各用户指向的是同一个文件因此只要其中一个用户修改了文件数据那么所有用户都可以看到文件数据的变化。
6.索引结点对FCB的改进 当找到文件名对应的目录项时才需要将索引结点调入内存索引结点中记录了文件的各种信息包括文件在外存中的存放位置根据“存放位置”即可找到文件。
存放在外存中的索引结点称为“磁盘索引结点”当索引结点放入内存后称为“内存索引结点”。相比之下内存索引结点中需要增加一些信息比如:文件是否被修改、此时有几个进程正在访问该文件等。
4.文件分配方式文件物理结构 在介绍这些分配方式之前先介绍一下什么是文件块磁盘块。
在内存管理中进程的逻辑地址空间被分为一个一个页面。
同样的在外存管理中为了方便对文件数据的管理文件的逻辑地址空间也被分为了一个一个的文件“块”。
于是文件的逻辑地址也可以表示为逻辑块号块内地址的形式。
用户通过逻辑地址来操作自己的文件操作系统要负责实现从逻辑地址到物理地址的映射。 1.连续分配
**连续分配方式要求每个文件在磁盘上占有一组连续的块。**如图所示
用户给出要访问的逻辑块号操作系统找到该文件对应的目录项FCB)
物理块号起始块号逻辑块号
当然还需要检查用户提供的逻辑块号是否合法逻辑块号≥长度就不合法)、
优点:支持顺序访问和直接访问即随机访问)连续分配的文件在顺序访问时速度最快
缺点:不方便文件拓展;存储空间利用率低会产生磁盘碎片 2.链接分配——隐式链接
链接分配采取离散分配的方式可以为文件分配离散的磁盘块。分为隐式链接和显式链接两种。
从逻辑块号到物理块号的转变 用户给出要访问的逻辑块号i操作系统找到该文件对应的目录项(FCB) 从目录项中找到起始块号即0号块将0号逻辑块读入内存由此知道1号逻辑块存放的物理块号于是读入1号逻辑块再找到2号逻辑块的存放位置…以此类推。 因此读入i号逻辑块总共需要i1次磁盘l/O。
结论:**采用链式分配隐式链接方式的文件只支持顺序访问不支持随机访问查找效率低。**另外指向下一个盘块的指针也需要耗费少量的存储空间。 3.链接分配——显式链接
把用于链接文件各物理块的指针显式地存放在一张表中。即文件分配表FAT,File Allocation Table)。如图所示 注意:一个磁盘仅设置一张FAT。开机时将FAT读入内存并常驻内存。FAT的各个表项在物理上连续存储且每一个表项长度相同因此“物理块号”字段可以是隐含的。 从逻辑块号到物理块号的转变
用户给出要访问的逻辑块号i操作系统找到该文件对应的目录项( FCB)从目录项中找到起始块号若i0则查询内存中的文件分配表FAT往后找到i号逻辑块对应的物理块号。逻辑块号转换成物理块号的过程不需要读磁盘操作。
结论:采用链式分配显式链接方式的文件支持顺序访问也支持随机访问想访问i号逻辑块时并不需要依次访问之前的 0~i-1号逻辑块)由于块号转换的过程不需要访问磁盘因此相比于隐式链接来说访问速度快很多。
显然显式链接也不会产生外部碎片也可以很方便地对文件进行拓展。 4.两种链接分配方式总结
隐式链接――除文件的最后一个盘块之外每个盘块中都存有指向下一个盘块的指针。文件目录包括文件第一块的指针和最后一块的指针。
优点:很方便文件拓展不会有碎片问题外存利用率高。缺点:只支持顺序访问不支持随机访问查找效率低指向下一个盘块的指针也需要耗费少量的存储空间。
显式链接――把用于链接文件各物理块的指针显式地存放在一张表中即文件分配表FATFileAllocation Table)。一个磁盘只会建立一张文件分配表。开机时文件分配表放入内存并常驻内存。
优点:很方便文件拓展不会有碎片问题外存利用率高并且支持随机访问。相比于隐式链接来说地址转换时不需要访问磁盘因此文件的访问效率更高。缺点:文件分配表的需要占用一定的存储空间。
5.索引分配
索引分配允许文件离散地分配在各个磁盘块中系统会为每个文件建立一张索引表索引表中记录了文件的各个逻辑块对应的物理块索引表的功能类似于内存管理中的页表――建立逻辑页面到物理页之间的映射关系)。索引表存放的磁盘块称为索引块。文件数据存放的磁盘块称为数据块。
从逻辑块号到物理块号的转变
用户给出要访问的逻辑块号i操作系统找到该文件对应的目录项FCB)从目录项中可知索引表存放位置将索引表从外存读入内存并查找索引表即可知道i号逻辑块在外存中的存放位置。可见索引分配方式可以支持随机访问。文件拓展也很容易实现(只需要给文件分配一个空闲块并增加一个索引表项即可)但是索引表需要占用一定的存储空间 如果一个文件的索引表太大一个磁盘块放不下那么如何解决呢
可以用以下三种方式解决:
①链接方案:如果索引表太大一个索引块装不下那么可以将多个索引块链接起来存放。 ②多层索引:建立多层索引原理类似于多级页表)。使第一层索引块指向第二层的索引块。还可根据文件大小的要求再建立第三层、第四层索引块。 ③混合索引:多种索引分配方式的结合。例如一个文件的顶级索引表中既包含直接地址索引直接指向数据块又包含一级间接索引指向单层索引表)、还包含两级间接索引指向两层索引表)。 总结
①链接方案 : 如果索引表太大一个索引块装不下那么可以将多个索引块链接起来存放。缺点:若文件很大索引表很长就需要将很多个索引块链接起来。想要找到i号索引块必须先依次读入0~i-1号索引块这就导致磁盘I/O次数过多查找效率低下。
②多层索引:建立多层索引(原理类似于多级页表。使第一层索引块指向第二层的索引块。还可根据文件大小的要求再建立第三层、第四层索引块。采用K层索引结构且顶级索引表未调入内存则访问一个数据块只需要K1次读磁盘操作。缺点:即使是小文件访问一个数据块依然需要K1次读磁盘。
③混合索引:多种索引分配方式的结合。例如一个文件的顶级索引表中既包含直接地址索引直接指向数据块又包含一级间接索引指向单层索引表)、还包含两级间接索引(指向两层索引表)。优点:对于小文件来说访问一个数据块所需的读磁盘次数更少。
6.三种分配方式总结 5.对空闲磁盘块的管理文件存储空间管理 1.文件卷
存储空间的划分:将物理磁盘划分为一个个文件卷(逻辑卷、逻辑盘)。所谓的文件卷就相当于电脑上的C盘D盘等。 2.空闲表法
为一个磁盘创建一个表来存储空闲磁盘块的位置。
如何分配磁盘块 : 与内存管理中的动态分区分配很类似为一个文件分配连续的存储空间。同样可采用首次适应、最佳适应、最坏适应等算法来决定要为文件分配哪个区间。
如何回收磁盘块:与内存管理中的动态分区分配很类似当回收某个存储区时需要有四种情况―—①回收区的前后都没有相邻空闲区;②回收区的前后都是空闲区;③回收区前面是空闲区;④回收区后面是空闲区。总之回收时需要注意表项的合并问题。 3.空闲链表法
空闲链表法分为空闲盘块链和空闲盘区链。 空闲盘块链
操作系统保存着链头、链尾指针。如何分配:若某文件申请K个盘块则从链头开始依次摘下K个盘块分配并修改空闲链的链头指针。如何回收:回收的盘块依次挂到链尾并修改空闲链的链尾指针。适用于离散分配的物理结构。为文件分配多个盘块时可能要重复多次操作。 空闲盘区链
操作系统保存着链头、链尾指针。如何分配:若某文件申请K个盘块则可以采用首次适应、最佳适应等算法从链头开始检索按照算法规则找到一个大小符合要求的空闲盘区分配给文件。若没有合适的连续空闲块也可以将不同盘区的盘块同时分配给一个文件注意分配后可能要修改相应的链指针、盘区大小等数据。如何回收:若回收区和某个空闲盘区相邻则需要将回收区合并到空闲盘区中。若回收区没有和任何空闲区相邻将回收区作为单独的一个空闲盘区挂到链尾。离散分配、连续分配都适用。为一个文件分配多个盘块时效率更高 4.位示图法
位示图:每个二进制位对应一个盘块。在本例中“0”代表盘块空闲“1”代表盘块已分配。位示图一般用连续的“字”来表示如本例中一个字的字长是16位字中的每一位对应一个盘块。因此可以用(字号位号对应一个盘块号。当然有的题目中也描述为行号列号)
(字号,位号)(i j) 的二进制位对应的盘块号 b ni j
b号盘块对应的字号i b/n位号j b%n。
如何分配:若文件需要K个块
①顺序扫描位示图找到K个相邻或不相邻的“0”;
②根据字号、位号算出对应的盘块号将相应盘块分配给文件;
③将相应位设置为“1”。
如何回收:
①根据回收的盘块号计算出对应的字号、位号;
②将相应二进制位设为“0”。 5.成组链接法
空闲表法、空闲链表法不适用于大型文件系统因为空闲表或空闲链表可能过大。UNIX系统中采用了成组链接法对磁盘空闲块进行管理。 文件卷的目录区中专门用一个磁盘块作为“超级块”当系统启动时需要将超级块读入内存。并且要保证内存与外存中的“超级块”数据一致。如图所示 超级块中存储的内容 如何分配?
Eg :需要100个空闲块 ①检查第一个分组的块数是否足够。100100是足够的。
②分配第一个分组中的100个空闲块。但是由于300号块内存放了再下一组的信息因此300号块的数据需要复制到超级块中。
Eg :需要1个空闲块 ①检查第一个分组的块数是否足够。1100因此是足够的。
②分配第一个分组中的1个空闲块并修改相应数据
如何回收? Eg :假设每个分组最多为100个空闲块此时第一个分组已有99个块还要再回收一块。
Eg : 假设每个分组最多为100个空闲块此时第一个分组已有100个块还要再回收一块。需要将超级块中的数据复制到新回收的块中并修改超级块的内容让新回收的块成为第一个分组。
6.文件的基本操作
1.创建文件
进行Create系统调用时需要提供的几个主要参数:
所需的外存空间大小如:一个盘块即1KB)文件存放路径“D:/Demo”)文件名这个地方默认为“新建文本文档.txt”)
操作系统在处理Create系统调用时主要做了两件事:
在外存中找到文件所需的空间结合上小节学习的空闲链表法、位示图、成组链接法等管理策略找到空闲空间)根据文件存放路径的信息找到该目录对应的目录文件此处就是 D:/Demo目录在目录中创建该文件对应的目录项。目录项中包含了文件名、文件在外存中的存放位置等信息。
2.删除文件
进行Delete系统调用时需要提供的几个主要参数:
文件存放路径“D:/Demo”)文件名“test.txt”)
操作系统在处理Delete系统调用时主要做了几件事:
根据文件存放路径找到相应的目录文件从目录中找到文件名对应的目录项。根据该目录项记录的文件在外存的存放位置、文件大小等信息回收文件占用的磁盘块。(回收磁盘块时根据空闲表法、空闲链表法、位图法等管理策略的不同需要做不同的处理)从目录表中删除文件对应的目录项。
3.打开文件
在很多操作系统中在对文件进行操作之前要求用户先使用open系统调用“打开文件”需要提供的几个主要参数:
文件存放路径“D:/Demo”)文件名 “test.txt”)要对文件的操作类型如:r只读;rw读写等)
操作系统在处理open系统调用时主要做了几件事:
根据文件存放路径找到相应的目录文件从目录中找到文件名对应的的目录项并检查该用户是否有指定的操作权限。将目录项复制到内存中的“打开文件表”中。并将对应表目的编号返回给用户。之后用户使用打开文件表的编号来指明要操作的文件。 需要注意的是有两张打开文件表一个是进程自带的另一个是系统的只有一张。 4.关闭文件
进程使用完文件后要“关闭文件”。 操作系统在处理Close系统调用时主要做了几件事:
将进程的打开文件表相应表项删除回收分配给该文件的内存空间等资源系统打开文件表的打开计数器count 减1若count 0则删除对应表项。
5.读文件
进程使用read系统调用完成写操作。需要指明是哪个文件在支持“打开文件”操作的系统中只需要提供文件在打开文件表中的索引号即可)还需要指明要读入多少数据如:读入1KB指明读入的数据要放在内存中的什么位置。操作系统在处理read 系统调用时会从读指针指向的外存中将用户指定大小的数据读入用户指定的内存区域中。
6.写文件
进程使用write系统调用完成写操作需要指明是哪个文件在支持“打开文件”操作的系统中只需要提供文件在打开文件表中的索引号即可还需要指明要写出多少数据如:写出1KB)写回外存的数据放在内存中的什么位置操作系统在处理write系统调用时会从用户指定的内存区域中将指定大小的数据写回写指针指向的外存。
7.文件共享
1.基于索引节点的共享方式硬链接
知识回顾:索引结点是一种文件目录瘦身策略。由于检索文件时只需用到文件名因此可以将除了文件名之外的其他信息放到索引结点中。这样目录项就只需要包含文件名、索引结点指针。 索引结点中设置一个链接计数变量 count用于表示链接到本索引结点上的用户目录项数。 若count 2说明此时有两个用户目录项链接到该索引结点上或者说是有两个用户在共享此文件。若某个用户决定“删除”该文件则只是要把用户目录中与该文件对应的目录项删除且索引结点的count值减1。 若count0说明还有别的用户要使用该文件暂时不能把文件数据删除否则会导致指针悬空。当count 0时系统负责删除文件。
2.基于符号链的共享方式软链接
当User3访问“ccc”时操作系统判断文件“ccc”属于Link类型文件于是会根据其中记录的路径层层查找目录最终找到User1的目录表中的“aaa”表项于是就找到了文件1的索引结点。类似于快捷方式。 8.文件保护
1.口令保护
为文件设置一个“口令”(如: abc112233用户请求访问该文件时必须提供“口令”。
口令一般存放在文件对应的FCB或索引结点中。用户访问文件前需要先输入“口令”操作系统会将用户提供的口令与FCB中存储的口令进行对比如果正确则允许该用户访问文件。
优点:保存口令的空间开销不多验证口令的时间开销也很小。
缺点:正确的“口令”存放在系统内部不够安全。
2.加密保护
使用某个“密码”对文件进行加密在访问文件时需要提供正确的“密码”才能对文件进行正确的解密。 Eg:一个最简单的加密算法――异或加密。 假设用于加密/解密的“密码”为“01001”。 优点:保密性强不需要在系统中存储“密码”。
缺点:编码/译码或者说加密/解密要花费一定时间。
3.访问控制
在每个文件的FCB或索引结点中增加一个访问控制列表(Access-Control List, ACL)该表中记录了各个用户可以对该文件执行哪些操作。如图所示 精简的访问列表:以“组”为单位标记各“组”用户可以对文件执行哪些操作。如:分为系统管理员、文件主、文件主的伙伴、其他用户几个分组。当某用户想要访问文件时系统会检查该用户所属的分组是否有相应的访问权限。 4.总结 9.文件的层次结构 用一个例子来辅助记忆文件系统的层次结构:
假设某用户请求删除文件“D:/工作目录/学生信息.xlsx”的最后100条记录。
用户需要通过操作系统提供的接口发出上述请求一用户接口。由于用户提供的是文件的存放路径因此需要操作系统一层一层地查找目录找到对应的目录项――文件目录系统不同的用户对文件有不同的操作权限因此为了保证安全需要检查用户是否有访问权限―一存取控制模块存取控制验证层)验证了用户的访问权限之后需要把用户提供的“记录号”转变为对应的逻辑地址――逻辑文件系统与文件信息缓冲区知道了目标记录对应的逻辑地址后还需要转换成实际的物理地址――物理文件系统要删除这条记录必定要对磁盘设备发出请求――设备管理程序模块删除这些记录后会有一些盘块空闲因此要将这些空闲盘块回收――辅助分配模块。
10.磁盘结构
磁盘的表面由一些磁性物质组成可以用这些磁性物质来记录二进制数据。磁盘的盘面被划分成一个个磁道。这样的一个“圈”就是一个磁道。一个磁道又被划分成一个个扇区每个扇区就是一个“磁盘块”。各个扇区存放的数据量相同如1KB)。 所有盘面中相对位置相同的磁道组成柱面。 可用(柱面号盘面号扇区号来定位任意一个“磁盘块”。 可根据该地址读取一个“块” ①根据“柱面号”移动磁臂让磁头指向指定柱面;②激活指定盘面对应的磁头;③磁盘旋转的过程中指定的扇区会从磁头下面划过这样就完成了对指定扇区的读/写。 磁盘分类 11.磁盘调度算法
1.一次磁盘读/写操作需要的时间 寻找时间(寻道时间)Ts:在读/写数据前将磁头移动到指定磁道所花的时间。 ①启动磁头臂是需要时间的。假设耗时为s; ②移动磁头也是需要时间的。假设磁头匀速移动每跨越一个磁道耗时为m总共需要跨越n条磁道。则: 寻道时间Ts s m*n 延迟时间T:通过旋转磁盘使磁头定位到目标扇区所需要的时间。设磁盘转速为r(单位:转/秒或转/分则平均所需的延迟时间T(1/2)*(1/r) 1/2r。 1/r就是转一圈需要的时间。找到目标扇区平均需要转半圈因此再乘以1/2 传输时间Tt:从磁盘读出或向磁盘写入数据所经历的时间假设磁盘转速为r此次读/写的字节数为b每个磁道上的字节数为N。则: 传输时间Tt (1/r)*(b/N) b/(rN) 每个磁道要可存N字节的数据因此b字节的数据需要b/N个磁道才能存储。而读/写一个磁道所需的时间刚好又是转一圈所需要的时间1/r。 总的平均存取时间 TTs 1/2r b/(rN)
延迟时间和传输时间都与磁盘转速相关且为线性相关。而转速是硬件的固有属性因此操作系统也无法优化延迟时间和传输时间。但是操作系统的磁盘调度算法会直接影响寻道时间。
2.先来先服务算法
根据进程请求访问磁盘的先后顺序进行调度。 3.最短寻找时间优先SSTF
SSTF算法会优先处理的磁道是与当前磁头最近的磁道。可以保证每次的寻道时间最短但是并不能保证总的寻道时间最短。(其实就是贪心算法的思想只是选择眼前最优但是总体未必最优) 4.扫描算法SCAN
SSTF算法会产生饥饿的原因在于:磁头有可能在一个小区域内来回来去地移动。为了防止这个问题可以规定只有磁头移动到最外侧磁道的时候才能往内移动移动到最内侧磁道的时候才能往外移动。这就是扫描算法SCAN)的思想。由于磁头移动的方式很像电梯因此也叫电梯算法。 5.LOOK调度算法
扫描算法SCAN)中只有到达最边上的磁道时才能改变磁头移动方向事实上处理了184号磁道的访问请求之后就不需要再往右移动磁头了。LOOK调度算法就是为了解决这个问题如果在磁头移动方向上已经没有别的请求就可以立即改变磁头移动方向。(边移动边观察因此叫LOOK)。 6.循环扫描算法C-SCAN
SCAN算法对于各个位置磁道的响应频率不平均而C-SCAN算法就是为了解决这个问题。规定只有磁头朝某个特定方向移动时才处理磁道访问请求而返回时直接快速移动至起始端而不处理任何请求。 7.C-LOOK调度算法
C-SCAN 算法的主要缺点是只有到达最边上的磁道时才能改变磁头移动方向并且磁头返回时不一定需要返回到最边缘的磁道上。C-LOOK算法就是为了解决这个问题。如果磁头移动的方向上已经没有磁道访问请求了就可以立即让磁头返回并且磁头只需要返回到有磁道访问请求的位置即可。 12.减少延迟时间的方法 假设要连续读取橙色区域的2、3、4扇区: 磁头读取一块的内容也就是一个扇区的内容后需要一小段时间处理而盘片又在不停地旋转 因此如果2、3号扇区相邻着排列则读完2号扇区后无法连续不断地读入3号扇区 必须等盘片继续旋转3号扇区再次划过磁头才能完成扇区读入。
结论:磁头读入一个扇区数据后需要一小段时间处理如果逻辑上相邻的扇区在物理上也相邻则读入几个连续的逻辑扇区可能需要很长的“延迟时间”。 1.交替编号
若采用交替编号的策略即让逻辑上相邻的扇区在物理上有一定的间隔可以使读取连续的逻辑扇区所需要的延迟时间更小。如图所示。 2.磁盘地址结构的设计
思考:为什么磁盘的物理地址是柱面号盘面号扇区号)而不是(盘面号柱面号扇区号)
答:读取地址连续的磁盘块时采用柱面号盘面号扇区号的地址结构可以减少磁头移动消耗的时间
3.错位命名 13.磁盘的管理
1.磁盘初始化
磁盘初始化:
Step 1:进行低级格式化物理格式化将磁盘的各个磁道划分为扇区。一个扇区通常可分为头、数据区域如512B大小、尾三个部分组成。管理扇区所需要的各种数据结构一般存放在头、尾两个部分包括扇区校验码如奇偶校验、CRC循环冗余校验码等校验码用于校验扇区中的数据是否发生错误)Step 2:将磁盘分区每个分区由若干柱面磁道组成即分为我们熟悉的C盘、D盘、E盘)step 3:进行逻辑格式化创建文件系统。包括创建文件系统的根目录、初始化存储空间管理所用的数据结构如位示图、空闲分区表) 2.引导块
计算机开机时需要进行一系列初始化的工作这些初始化工作是通过执行初始化程序自举程序完成的。初始化程序可以放在ROM(只读存储器中。ROM中的数据在出厂时就写入了并且以后不能再修改 。
初始化程序程序自举程序放在ROM中存在什么问题?万一需要更新自举程序将会很不方便因为ROM中的数据无法更改。如何解决呢?
ROM中只存放很小的“自举装入程序”。开机时计算机先运行“自举装入程序”通过执行该程序就可找到引导块并将完整的“自举程序”读入内存完成初始化完整的自举程序放在磁盘的启动块(即引导块/启动分区)上启动块位于磁盘的固定位置。拥有启动分区的磁盘称为启动磁盘或系统磁盘c:盘)
3.坏块的管理
坏了、无法正常使用的扇区就是“坏块”。这属于硬件故障操作系统是无法修复的。应该将坏块标记出来以免错误地使用到它。对于简单的磁盘可以在逻辑格式化时建立文件系统时)对整个磁盘进行坏块检查标明哪些扇区是坏扇区比如:在FAT表上标明。在这种方式中坏块对操作系统不透明)对于复杂的磁盘磁盘控制器磁盘设备内部的一个硬件部件会维护一个坏块链表。在磁盘出厂前进行低级格式化物理格式化时就将坏块链进行初始化。会保留一些“备用扇区”用于替换坏块。这种方案称为扇区备用。且这种处理方式中坏块对操作系统透明。
五、I/O管理
1.I/O设备的概念
“I/O” 就是“输入/输出”(Input/Output)I/O设备就是可以将数据输入到计算机或者可以接收计算机输出数据的外部设备属于计算机中的硬件部件。
2.I/O控制器
1.含义
CPU无法直接控制l/O设备的机械部件因此I/O设备还要有一个电子部件作为CPU和I/O设备机械部件之间的“中介”用于实现CPU对设备的控制。这个电子部件就是I/O控制器又称设备控制器。CPU可控制I/o控制器又由I/O控制器来控制设备的机械部件。
2.功能 3.组成 3.I/O控制方式
1.程序直接控制方式
完成一次读/写操作的流程图(以读操作为例) 流程图 2.中断驱动方式
由于程序直接控制方式CPU利用率低忙等所以提出了中断驱动方式。 3.DMA方式
虽然中断驱动方式解决了程序直接控制方式的问题但是每一次只能读/写一个字导致CPU频繁切换耗费了很多时间。于是人们又发明了DMA方式。 DMA控制器 4.通道控制方式
通道控制方式是为了解决DMA方式连续存储的问题 5.四种方式总结 4.I/O软件层次结构
1.知识总览 2.用户层软件 用户层软件实现了与用户交互的接口用户可直接使用该层提供的、与I/o操作相关的库函数对设备进行操作。 用户层软件将用户请求翻译成格式化的I/o请求并通过“系统调用”请求操作系统内核的服务。
3.设备独立性软件
设备独立性软件又称设备无关性软件。与设备的硬件特性无关的功能几乎都在这一层实现。
主要功能
向上层提供统一的调用接口如read/write系统调用)设备的保护。原理类似与文件保护。设备被看做是一种特殊的文件不同用户对各个文件的访问权限是不一样的同理对设备的访问权限也不一样。差错处理设备独立性软件需要对一些设备的错误进行处理设备的分配与回收数据缓冲区管理可以通过缓冲技术屏蔽设备之间数据交换单位大小和传输速度的差异建立逻辑设备名到物理设备名的映射关系;根据设备类型选择调用相应的驱动程序
用户或用户层软件发出I/o操作相关系统调用的系统调用时需要指明此次要操作的I/o设备的逻辑设备名eg:去学校打印店打印时需要选择打印机1/打印机2/打印机3其实这些都是逻辑设备名)
**设备独立性软件需要通过“逻辑设备表LUTLogical UnitTable”来确定逻辑设备对应的物理设备并找到该设备对应的设备驱动程序。**如图所示 操作系统系统可以采用两种方式管理逻辑设备表(LUT) :
第一种方式整个系统只设置一张LUT这就意味着所有用户不能使用相同的逻辑设备名因此这种方式只适用于单用户操作系统。第二种方式为每个用户设置一张LUT各个用户使用的逻辑设备名可以重复适用于多用户操作系统。系统会在用户登录时为其建立一个用户管理进程而LUT就存放在用户管理进程的PCB中。
4.驱动设备
思考:为何不同的设备需要不同的设备驱动程序?
不同设备的内部硬件特性也不同这些特性只有厂家才知道因此厂家须提供与设备相对应的驱动程序CPU执行驱动程序的指令序列来完成设置设备寄存器检查设备状态等工作。 5.中断处理程序
当I/o任务完成时I/o控制器会发送一个中断信号系统会根据中断信号类型找到相应的中断处理程序并执行。中断处理程序的处理流程如下: 6.总结 5.I/O核心子系统
1.知识总览 这些功能在哪些层次上实现呢 2.I/O调度
I/O调度:用某种算法确定一个好的顺序来处理各个I/o请求。 如:磁盘调度先来先服务算法、最短寻道优先算法、SCAN算法、C-SCAN算法、LOOK算法、C-LOOK算法。
当多个磁盘I/o请求到来时用某种调度算法确定满足I/o请求的顺序。
同理打印机等设备也可以用先来先服务算法、优先级算法、短作业优先等算法来确定IV/o调度顺序。
3.设备保护
操作系统需要实现文件保护功能不同的用户对各个文件有不同的访问权限如:只读、读和写等。 在UNIx系统中设备被看做是一种特殊的文件每个设备也会有对应的FCB。当用户请求访问某个设备时系统根据FCB中记录的信息来判断该用户是否有相应的访问权限以此实现“设备保护”的功能。(参考“文件保护”小节)
6.假脱机技术SPOOLing技术
1.脱机技术 手工操作阶段:主机直接从l/o设备获得数据由于设备速度慢主机速度很快。人机速度矛盾明显主机要浪费很多时间来等待设备。因此在批处理阶段引入了脱机输入/输出技术用磁带完成). Tips:为什么称为“脱机”一脱离主机的控制进行的输入/输出操作。 2.假脱机技术
“假脱机技术”又称“SPOOLing 技术”用软件的方式模拟脱机技术。SPOQLing系统的组成如下: “输入井”模拟脱机输入时的磁带用于收容I/o设备输入的数据 “输出井”模拟脱机输出时的磁带用于收容用户进程输出的数据 “输入进程”模拟脱机输入时的外围控制机 “输出进程”模拟脱机输出时的外围控制机
要实现SPOOLing 技术必须要有多道程序技术的支持。系统会建立“输入进程”和“输出进程”。
7.设备的分配和回收
1.知识总览 2.设备分配时考虑的因素 1.固有属性 设备的固有属性可分为三种:独占设备、共享设备、虚拟设备。
独占设备—— 一个时段只能分配给一个进程如打印机)共享设备――可同时分配给多个进程使用如磁盘)各进程往往是宏观上同时共享使用设备而微观上交替使用。虚拟设备――采用SPOOLing 技术将独占设备改造成虚拟的共享设备可同时分配给多个进程使用如采用SPOOLing技术实现的共享打印机
2.分配算法 先来先服务优先级高者优先短任务优先…
3.安全性 从进程运行的安全性上考虑设备分配有两种方式: 安全分配方式: 为进程分配一个设备后就将进程阻塞本次I/O完成后才将进程唤醒。(eg:考虑进程请求打印机打印输出的例子) 一个时段内每个进程只能使用一个设备 优点:破坏了“请求和保持”条件不会死锁 缺点:对于一个进程来说CPU和I/o设备只能串行工作 不安全分配方式: 进程发出I/o请求后系统为其分配I/O设备进程可继续执行之后还可以发出新的I/o请求。只有某个l/o请求得不到满足时才将进程阻塞。 一个进程可以同时使用多个设备 优点:进程的计算任务和I/o任务可以并行处理使进程迅速推进 缺点:有可能发生死锁(死锁避免、死锁的检测和解除)
3.静态分配和动态分配
静态分配:进程运行前为其分配全部所需资源运行结束后归还资源。破坏了“请求和保持”条件不会发生死锁动态分配:进程运行过程中动态申请设备资源
4.设备分配中的数据结构
“设备、控制器、通道”之间的关系: 设备控制表DCT)系统为每个设备配置一张DCT用于记录设备情况 控制器控制表(COCT)每个设备控制器都会对应一张COCT。操作系统根据COCT的信息对控制器进行操作和管理。 通道控制表CHCT)每个通道都会对应一张CHCT。操作系统根据CHCT的信息对通道进行操作和管理。 系统设备表(SDT):记录了系统中全部设备的情况每个设备对应一个表目。
5.设备分配的步骤
①根据进程请求的物理设备名查找SDT注:物理设备名是进程请求分配设备时提供的参数)
②根据SDT找到DCT若设备忙碌则将进程PCB挂到设备等待队列中不忙碌则将设备分配给进程。
③根据DCT找到COCT若控制器忙碌则将进程PCB挂到控制器等待队列中不忙碌则将控制器分配给进程。
④根据COCT找到CHCT若通道忙碌则将进程PCB挂到通道等待队列中不忙碌则将通道分配给进程。
注∶只有设备、控制器、通道三者都分配成功时这次设备分配才算成功之后便可后动I/O设备进行数据传送。
缺点: ①用户编程时必须使用“物理设备名”底层细节对用户不透明不方便编程
②若换了一个物理设备则程序无法运行
③若进程请求的物理设备正在忙碌则即使系统中还有同类型的设备进程也必须阻塞等待
改进方法:建立逻辑设备名与物理设备名的映射机制用户编程时只需提供逻辑设备名 6.设备分配步骤的改进
①根据进程请求的逻辑设备名查找SDT(注:用户编程时提供的逻辑设备名其实就是“设备类型”)
②查找SDT找到用户进程指定类型的、并且空闲的设备将其分配给该进程。操作系统在逻辑设备表LUT)中新增一个表项。
③根据DCT找到cOCT若控制器忙碌则将进程PCB挂到控制器等待队列中不忙碌则将控制器分配给进程。
④根据COCT找到CHCT若通道忙碌则将进程PCB挂到通道等待队列中不忙碌则将通道分配给进程。 逻辑设备表 8.缓冲区管理
1.知识总览 2.含义和作用
含义
缓冲区是一个存储区域可以由专门的硬件寄存器组成也可利用内存作为缓冲区。使用硬件作为缓冲区的成本较高容量也较小一般仅用在对速度要求非常高的场合如存储器管理中所用的联想寄存器由于对页表的访问频率极高因此使用速度很快的联想寄存器来存放页表项的副本)一般情况下更多的是利用内存作为缓冲区“设备独立性软件”的缓冲区管理就是要组织管理好这些缓冲区
作用 3.单缓冲
假设某用户进程请求某种块设备读入若干块的数据。若采用单缓冲的策略操作系统会在主存中为其分配一个缓冲区若题目中没有特别说明一个缓冲区的大小就是一个块。如图所示 注意:当缓冲区数据非空时不能往缓冲区冲入数据只能从缓冲区把数据传出;当缓冲区为空时可以往缓冲区冲入数据但必须把缓冲区充满以后才能从缓冲区把数据传出。 处理一块数据的平均时间 4.双缓冲
假设某用户进程请求某种块设备读入若干块的数据。若采用双缓冲的策略操作系统会在主存中为其分配两个缓冲区若题目中没有特别说明一个缓冲区的大小就是一个块)。 假设TCM 假设TCM
结论:采用双缓冲策略处理一个数据块的平均耗时为Max (T,CM)。
5.循环缓冲区
将多个大小相等的缓冲区链接成一个循环队列。 注:以下图示中橙色表示已充满数据的缓冲区绿色表示空缓冲区。 6.缓冲池
缓冲池由系统中共用的缓冲区组成。
这些缓冲区按使用状况可以分为:空缓冲队列、装满输入数据的缓冲队列(输入队列)、装满输出数据的缓冲队列输出队列。
另外根据一个缓冲区在实际运算中扮演的功能不同又设置了四种工作缓冲区:用于收容输入数据的工作缓冲区(hin)、用于提取输入数据的工作缓冲区sin)、用于收容输出数据的工作缓冲区(hout 、用于提取输出数据的工作缓冲区(sout)。 附录
笔记md文档版https://download.csdn.net/download/Cappuccino_jay/88542862