操作系统的目标
提供什么服务
- 用户接口
- 命令行
- 图形界面
- 执行程序
- IO操作
- 文件系统
- 通信
- 比如进程通信
- 错误检测
- 资源的分配
- 统计
- 获取资源的使用情况
- 保护
- 确保资源是被正确使用和访问的
如何让用户使用服务
- 用户接口下面加了一层System calls(系统调用)
- 通过系统调用来使用操作系统的服务。通过是API
- 提供运行程序和操作系统之间的接口。
通过系统调用调用特权指令
进程
进程的概念
- OS的基本特性是并发与共享,即在系统中同时存在几个相互独立的程序,他们交叉地运行,并共享资源。
- 资源的竞争
- 程序之间的合作和协同
- 程序之间的通信
- 要解决这些问题,用程序的概念已经不能描述程序在内存中运行的状态,必须引入新的概念-–进程
- 实现并发,进程是程序动态的执行过程
进程间的通信
- 共享内存,或者总线,这是物理连接
- 生产者-消费者,共享一个缓冲区(buffer),通过缓冲区双方决定自己的行为
直接通信
- 直接连接,是成对的连接,一般是双向的。
- 缺点,要使用进程唯一标识,要确定接收方和发送方,如果是双向的话,这样代码较难复用。
间接通信
- 有中间媒介,称为信箱(mail box)。
- 连接和多个线程相关,
- 一对进程可以共享多个通信连接
- 就是一个发送者和两个以上的接收者,如何确定谁接收?
- 允许一个连接最多同2个进程相关
- 只允许一个时刻有一个进程执行接受操作
- 允许系统任意选择接收者。发送者被通知谁是接收者。
- 就是一个发送者和两个以上的接收者,如何确定谁接收?
- 发送和接收分阻塞和非阻塞
- 通信链路(buffer)的大小可以用消息队列来描述,也可以说消息队列附加在连接上的。有3种方案:
- 零容量-0消息,发送者必须等待接收者。
- 有界容量-n个消息有限长度,若连接满了发送者必须等待。
- 无界容量-无限长度,发送者从不等待
进程具有二个基本属性:
- 是一个拥有资源的独立单位:它可独立分配虚地址空间、主存和其它
- 又是一个可独立调度和分派的基本单位。
- 这二个基本属性使进程成为并发执行的基本单位
- 在一些早期的OS中,比如大多数UNIX系统、Linux等,进程同时具有这二个属性。
- 由于进程是一个资源的拥有者,因而在进程创建、撤销、调度切换时,系统需要付出较大的时空开销。
- 进程的数目不宜过多,进程切换频率不宜过高,限制了并发程度。
线程
线程的概念
- 提高并发度,减少系统开销。
- 将进程的两个属性分开
- 对于拥有资源的基本单位,不对其进行频繁切换
- 对于调度(获取cpu的时间片)的基本单位,不作为拥有资源的单位,“轻装上阵”
- 以小的开销来提高并发度。
- 作为CPU调度单位,而进程只作为其他资源分配单位。
- 只拥有必不可少的资源,如:线程状态、程序计数器、寄存器上下文和栈
- 同样具有就绪、阻塞和执行三种基本状态
- 与同属一个进程的其它线程共享进程拥有的全部资源
- 可并发执行
减小并发执行的时间和空间开销(线程的创建、退出和调度),因此容许在系统中建立更多的线程来提高并发程度。
- 线程的创建时间比进程短;
- 线程的终止时间比进程短;
- 同进程内的线程切换时间比进程短;
- 由于同进程内线程间共享内存和文件资源,可直接进行不通过内核的通信;
进程和线程的比较
- 并发性︰在引入线程的OS中,不仅进程之间可以并发执行,而且在一个进程中的多个线程之间亦可并发执行,因而使oS具有更好的并发性,从而能更有效地使用系统资源和提高系统吞吐量。
- 拥有资源︰进程是拥有资源的独立单位
- 系统开销∶在创建或撤消进程时,系统都要为之分配或回收资源,如内存空间、IO设备等。因此,OS所付出的开销将明显地大于在创建或撤消线程时的开销。
- 地址空间和其他资源(如打开文件)︰进程间相互独立,同一进程的各线程间共享--某进程内的线程在其他进程不可见
- 通信︰进程间通信IPC,线程间可以直接读写进程数据段(如全局变量)来进行通信
- 需要进程同步和互斥手段的辅助,以保证数据的一致性。
- 调度︰线程上下文切换比进程上下文切换要快得多﹔
益处
- 响应度高:一个多线程的应用在执行中,即使其中的某个线程阻塞,其他的线程还可继续执行,从而提高响应速度
- 资源共享:同一进程的多个线程共享该进程的内存等资源
- 经济性:创建和切换线程的开销要低于进程。比如,Solaris中进程创建时间是线程创建的30倍,进程切换时间是线程切换的5倍。
- MP(多核心)体系结构的运用:多线程更适用于多处理机结构。
用户线程与内核线程
- 调度方式:内核线程的调度和切换与进程的调度和切换十分相似,用户线程的调度不需OS的支持。
- 调度单位:用户线程的调度以进程为单位进行,在采用时间片轮转调度算法时,每个进程分配相同的时间片。对内核级线程,每个线程分配时间片。
- 内核看不见用户线程。
线程模型
就是用户线程和内核线程的映射关系。
内核级线程是系统中“真正”的线程,因此对于用户级线程来说,用户程序运行用户级线程,必须要通过映射到内核级线程后,在内核级线程上运行它。
- 多对一,用户线程会阻塞,因为只有一个内核线程
- 一对一,会限制线程数目
- 多对多(最优解)
CPU调度
从就绪队列选进程执行
CPU调度算法
- 先来先服务(FCFS),非抢占式,适合长作业
- 短作业优先(SJF),短作业是非抢占式,剩余时间是抢占式,会出现饥饿,有个长作业可能永远无法执行。
- 优先权调度(Prioritv Schednling),可抢占,可非抢占。优先级随运行时间降低,随等待时间增加。
- 时间片轮转(Round Robin),每个进程得到固定时间的运行时间,会被抢占,会被移到队尾,如果时间片太小就会导致频繁上下文切换,如果太长就像先来先服务了。
- 多级队列调度(Multilevel Queue)
- 多级反馈队列调度算法(Multilevel Feedback Queue)
进程同步
保持共享数据的一致性,生产者和消费者问题中的buffer就难以保持数据一致。count++和--就不是原子操作。
临界资源
- 进程由代码、数据和PCB(进程控制块)组成,会有并发问题的部分其实在代码。
- 临界区(critical section):进程中访问临界资源的一段代码。
- 进入区(entry section):在进入临界区之前,检查可否进入临界区的一段代码。如果可以进入临界区,通常设置相应“正在访问临界区”标志。
- 退出区(exit section):也是一段代码,用于将"正在访问临界区"标志清除。
信号量
其实可以用代码来简单实现。
- 操作系统作为进程的管理者来处理互斥问题,信号量它提供的有效手段。
- S是与临界区内所使用的公用资源有关的信号量,来表示资源的数量。
- P(S):表示申请一个资源,原子操作
- V(S):表示释放一个资源,原子操作
- 初始化指定一个非负整数值,表示空闲资源总数在信号量经典定义下,信号量s的值不可能为负
- S≥0 可供并发进程使用的资源数
- S<0 其绝对值就是正在等待进入临界区的进程数
typedef struct{ int value; struct process * L; }semaphore semaphore s; P(s){ s.value--; if (s.value<0) { add this process to list s.Lblock //阻塞,防止空转自旋,浪费资源 } } V(s){ s.value++; if (s.value<= 0){ remove a process P from list s.L wakeup(P);//唤醒 } }
- 在进行互斥时,s的初始值一般为1,或n;
- 在同步(进程有先后顺序)时,就一般初始值为0;
死锁问题
-
哲学家就餐问题:
- 5个哲学家围圈,5个筷子放他们的间隙,5个人同时拿就会一人一支筷子,死锁,导致没有人可吃饭。
- 最多允许四个哲学家同时就坐。
- 同时拿起两根筷子,要么一支也不拿。
- 非对称解决,要么奇数号拿,要么偶数位拿。
- 5个哲学家围圈,5个筷子放他们的间隙,5个人同时拿就会一人一支筷子,死锁,导致没有人可吃饭。
-
读者-写者问题,就是读写锁差不多,
信号量小结
- S>0表示有S个资源可用S=0表示无资源可用
- S<0则|S|表示S等待队列中的进程个数
- P(S):表示申请一个资源
- V(S):表示释放一个资源。
- 信号量的初值应该大于等于0
死锁问题
死锁的4个必要条件
- Mutual exclusion: (互斥:一次只有一个进程可以使用一个资源)
- Hold and wait:(持有并等待:一个至少持有一个资源的进程等待获得额外的由其他进程所持有的资源)(请求并保持)
- No preemption: (不可抢占:一个资源只有当持有它的进程完成任务后,自由的释放)(非剥夺)
- Circular wait: (循环等待:等待资源的进程之间存在环)
死锁预防
打破其中一个死锁必要条件
- 互斥无法打破。
- 针对持有并等待。
- 要求进程在执行前一次申请全部的资源
- 没有资源时,可以申请资源。在申请更多其它资源之前,需要释放已有资源
- 利用率低,可能出现饥饿
- 针对不可抢占
- 如果一个进程的申请没有实现,它要释放所有占有的资源
- 抢占的资源放入进程等待资源列表中
- 只有进程能够重新得到旧的资源和新申请的资源时,才可以重新开始
- 针对循环等待
- 所有进程对资源的请求必须严格按资源序号递增的次序提出。
- 就是给资源标序号,如1、2、3。。
- 总有一个进程占据了较高序号的资源,它继续请求的资源必然是空闲的,可以一直向前推进。
- 在资源分配图中不可能出现环路,因而摒弃了“环路等待”条件
- 这种策略可以提高资源利用率,但在进程使用各类资源的顺序与系统规定的顺序不同时会造成资源浪费的情况。
- 所有进程对资源的请求必须严格按资源序号递增的次序提出。
都是限制对资源的请求,会有一些副作用
死锁避免
- 允许进程动态地申请资源,系统在进行资源分配之前,先计算资源分配的安全性。
- 若此次分配不会导致系统从安全状态向不安全状态转换,便可将资源分配给进程;否则不分配资源,进程必须阻塞等待。
- 安全状态是指系统的一种状态,在此状态下,系统能按某种顺序(例如P,、P.......Pn)来为各个进程分配其所需资源,直至最大需求,使每个进程都可顺序地一个个地完成。这个序列(P、P ....... .P)称为安全序列。
- 如果存在一个安全序列系统处于安全态。
- 若某一时刻不存在一个安全序列,则称系统处于不安全状态。
- 单实例资源,就打破请求不要循环即可。
- 多实例资源,就用银行家算法。
- 当进程首次申请资源时,要测试该进程对资源的最大需求量,如果系统现存的资源可以满足它的最大需求量则按当前的申请量分配资源,否则就推迟分配。
- 当进程在执行中继续申请资源时,先测试该进程本次申请的资源数是否超过了该资源所剩余的总量。若超过则拒绝分配资源,若能满足则按当前的申请量分配资源,否则也要推迟分配。
死锁检测和恢复
- 单实例资源检测,就直接检测是否有环。
- 多实例资源就看系统资源是否满足一个进程的需求。
- 死锁恢复
- 人工干预
- 终止进程
- 抢占,将资源从一个进程中抢出来,但有可能出现一个进程的资源一直被抢,会导致饥饿。
内存管理
- 源程序需要编译,链接,装入模块,装入程序到内存,在内存的位置需要确定。
- 可以在编译期确定,显然行不通,地址每次都不一样。都要重写源文件。
- 可以在装入的时候确定内存地址。
- 可以在运行期的时候确定内存地址。
背景
- 逻辑地址空间的概念同物理地址空间相关联,它是正确内存管理的中心。
- 逻辑地址:由CPU产生;也叫做虚拟空间。
- 物理地址:内存设备所读入的地址.
- MMU(Memory Management Unit,内存管理单元)
- 内存动态重定位,就物理地址到逻辑地址的映射。
内存分配
- 基址寄存器策略由来保护用户进程,将操作系统和用户进程分开。
- 基址寄存器包含最小物理地址的值;
- 限长寄存器包含逻辑地址的范围,每个逻辑地址必需比限长寄存器的值小。
固定分区分配
- 固定式分区是在作业装入之前,内存就被划分成若干个固定大小的连续分区。
- 划分工作可以由系统管理员完成,也可以由操作系统实现。
- 一旦划分完成,在系统运行期间不再重新划分,即分区的个数不可变,分区的大小不可变,所以,固定式分区又称为静态分区。
- 划分分区的方法如下:
- 分区固定大小,会有内碎片。
- 分区大小不等,会限制并发。
- 需要一个分区说明表记录分区的使用情况
动态分区分配
- 分区的划分是动态的,不是预先确定的
- 分区—可用的内存块,不同大小的分区分布在整个内存中。当一个进程到来的时候,它将从一个足够容纳它分区中分配内存。
- 操作系统包含以下信息:
- 分配的分区
- (hole)(空的分区)
- 空闲的分区表管理
- 表或链表
- 分配算法
- 寻找某个空闲分区,其大小需大于或等于程序的要求。若是大于要求,则将该分区分割成两个分区,其中一个分区为要求的大小并标记为“占用”,而另一个分区为余下部分并标记为“空闲”。分区的先后次序通常是从内存低端到高端。
- 释放算法
- 需要将相邻的空闲分区合并成一个空闲分区。(这时要解决的问题是∶合并条件的判断)
- 怎样从一个空的分区序列中满足一个申请需要?
- First-fit(首先适应): 分配最先找到的合适的分区。
- Best-fit(最佳适应):搜索整个序列,找到适合条件的最小的分区进行分配。
- Worst-fit(最差适应): 搜索整个序列,寻找最大的分区进行分配。
最差适应最拉跨。
- 外碎片问题
- 可变式分区的碎片问题:在系统不断地分配和回收中,必定会出现一些不连续的小的空闲区,称为外碎片。虽然可能所有碎片的总和超过某一个作业的要求,但是由于不连续而无法分配。
- 解决方法——碎片拼接(会耗费时间),动态重定位
分页
-
允许进程的物理内存空间可以不连续,而不是像分区那样每个进程的内存空间是连续。进而解决内存外碎片问题。
-
但是有内碎片,要将程序全部装入内。
-
把物理内存分成大小固定的块。
-
把逻辑内存也分为固定大小的块,叫做页。
-
有页表将逻辑地址和物理地址转换。
-
CPU产生的逻辑地址被分为:
- Page number(页号)
- 它包含每个页在物理内存中的基址,用来作为页表的索引。
- Page offset(偏移)
- 同基址相结合,用来确定送入内存设备的物理内存地址。
- Page number(页号)
-
因为页表太大不太可能直接放在CPU的寄存器中,要放到主存中,这样就会有两次访问内存,性能较低,遂引入TLB(translation look-aside buffers,联想寄存器)
如果需要访问的内容不在TBL中,再去主存中查页表。
-
基本内存地址变换机构(涉及的内容)
- 实现从逻辑地址到物理地址的转换:将用户程序中的页号变换成内存中的物理块号
-
找到对应进程的地址过程如下
分段
- 分页有缺点
- 没有从用户(大概是从程序员的角度)的角度来区分,一视同仁的将数据和运行部分都拆开成等大小的页。
- 分段就从用户的的角度将运行程序不同模块进行拆分,分段。
地址转换和分页类似不赘述。
虚拟内存
上面提到的内存管理,分页分段啥的,都要将程序全部装进内存,显然是不好用的,比如进程太多,内存装不下,啥的。遂引入虚拟内存。
当然了,内存不够可以直接加(物理扩容)。但是没有钱,就用虚拟内存(逻辑扩容)。
程序的局部性原理
- 时间局部性:
- 如果程序中的某条指令一旦执行,则不久的将来该指令可能再次被 执行(比如循环);
- 如果某个存储单元被访问,则不久以后该存储单元可能再次被访问(比如循环体中的某些变量)。
- 产生时间局限性的典型原因是在程序中存在着大量的循环操作。
- 空间局部性:
- 一旦程序访问了某个存储单元,则在不久的将来,其附近的存储单元也最有可能被访问。即程序在一段时间内所访问的地址,可能集中在一定的范围内(比如数组),其典型原因是程序(代码)是顺序执行的。
由局部性原理,那虚拟内存技术就好办了
- 虚拟内存是一种允许进程部分装入内存就可以执行的技术。
- 局部性原理:时间局部性,空间局部性
- 只有运行的部分程序需要在内存中
- 逻辑地址空间能够比物理地址空间大
- 必须允许页面能够被换入和换出
- 特点
- 是离散性的,不连续的。
- 是多次性的,同一个内容可以多次装入内存。
调页策略
-
就是决定哪些页会被调任内存。
-
预调页策略
- 主动的页面调入策略,即把那些预计很快会被访问的程序或数据所在的页面,预先调入内存。预测的准确率不高(50% ),主要用于进程的首次调入。也有的系统将预调页策略用于请求调页
-
请求调页策略
- 当进程在运行中发生缺页时,由系统将缺页调入内存。目前虚拟存储器系统大多采用此策略。在调页时须花费较大的系统开销,如需频繁启动磁盘I/O。
- 只有在一个页需要的时候才把它换入内存
- 需要很少的I/O
- 需要很少的内存
- 快速响应)
- 多用户
- 需要页 → 查阅此页 → 不在内存 → 换入内存
-
请求调页使用的技术
- 对进程页表的修改
- 缺页中断的支持
-
对于页表的修改
- 它是在纯分页的页表机制上形成的,由于只将应用程序的一部分调入内存,还有一部分仍在磁盘上,故需在页表中再增加若干项,供程序(数据)在换进、换出时参考。
-
缺页中断机构
- 在请求分页系统中,每当所要访问的页面不在内存时,便要产生缺页中断,请求OS将所缺页调入内存。与一般中断的主要区别在于:
- 缺页中断在指令执行期间产生和处理中断信号,而一般中断在一条指令执行完后会产生中断检查和处理中断信号。
- 缺页中断返回到该指令的开始重新执行该指令,而一般中断返回到该指令的下一条指令执行。
- 一条指令在执行期间,可能产生多次缺页中断。
- 在请求分页系统中,每当所要访问的页面不在内存时,便要产生缺页中断,请求OS将所缺页调入内存。与一般中断的主要区别在于:
页面置换
- 如果没有空闲帧,需要两个页面传输,一个换出,一个换入。
- 可以通过修改位来降低额外开销。
- 修改(脏)位来防止页面转移过多,毕竟内存中的内容被改了,写入外存理所应当一举两得。
- 只有被修改的页面才写入磁盘
- 页置换实现了逻辑内存和物理内存的划分—在一个较小的物理内存基础之上可以提供一个大的虚拟内存。
页面置换算法
- 在进程运行过程中,如果发生缺页,而内存中又无空闲块时,怎么办?
- 将内存中的某一页换到磁盘的对换区
- 将哪个页面调出?
- 根据页面置换算法来确定
- 置换算法的好坏将直接影响系统的性能,不适当的算法可能会导致进程发生 “抖动”(Thrashing)。
- 从理论上讲,应将那些以后不再被访问的页面换出,或把那些在较长时间内不会再被访问的页面换出。以期将低缺页率。
- 算法:
- 最佳算法(OPT, optimal)
- 是在已知调用序列的情况下
- 已经在内存中的页,选其中最长时间不会被调用的页换出去。
- 但实际情况是程序的调用是很难预知的。所以它是理论上最优的算法,即缺页率最低。
- 先进先出算法(FIFO)
- 就简单,谁先进的谁会就先被换出,显然缺页率高。
- 最近最久未使用算法(LRU,Least Recently Used)
- 使用离过去最近的情况作为不远将来的近似,可以选择最近最少使用的页进行置换。
- 根据过去,可以知道以前的调用序列,要换页时,选择过去很久未使用的页,将其换出。
- LRU选择最长时间没有使用的页。
- 实现LRU算法需要硬件支持,记录物理帧的使用情况
- LRU近似算法(clock)
- 在没有相关硬件时,可以使用此近似算法。
- 每个页都加一个访问位,初始值为0,当页是访问页时设位1。
- 最佳算法(OPT, optimal)
帧分配
- 如何给进程分配一定的空闲内存?
- 就根据每个进程所需要的最少的页的数目
- 保证进程正常运行所需的最小物理块数
- 若系统为某进程所分配的物理块数少于此值时,进程将无法正常运行(频繁发生缺页)
- 这个数目取决于指令的格式、功能和寻址方式。
- 最多能分配多少帧?
- 首要的肯定是和内存大小直接相关。
- 和主要的分配策略:
- 平均分配
- 就每个进程的分配一样的大小
- 按比例分配
- 根据进程的大小比例来分
- 优先分配
- 根据优先级,越高获得的内存越多
- 平均分配
抖动(Thrashing)
- 如果进程分配到的帧数量小于计算机体系结构所要求的最小数量,那么必须暂停进行执行。并将其置换出去,使其所有分配帧空闲。
- 为什么?
- 如果进程没有这些必需的帧,那么很快会出现缺页,此时需置换某个页,然而,其所有页都在使用,置换出去的页立刻又需要置换进来,因此,会不断的产生缺页。
- 这种频繁的调页行为称作颠簸,也叫抖动。
- 如果一个进程没有足够的页,那么缺页率将很高,这将导致
- CPU利用率低下,因为大部分时间都在io,换页
- 操作系统认为需要增加多道程序设计的道数
- 系统中将加入一个新的进程
- 当进程个数达到一定数量时,内存紧张,采用全局置换算法会引起更多的缺页错误
- 进程在磁盘等待队列等待换页,导致更长的等待队列,而就绪队列变空.CPU利用率进一步降低,会继续增加多道程序的程度,出现颠簸
恶性循环
- 如何解决抖动
- 工作集窗口(△)是指对于给定的访问序列选取定长的区间,落在工作集窗口中的页面集合称为工作集
- 正确选择工作集窗口(△)的大小,对存储器的有效利用和系统吞吐量的提高,都将产生重要的影响。
- 就是将进程需要装入内存的局部页 你,小于系统提供的内存。即可解决抖动。
文件系统
分类
- 系统文件
- 由系统软件构成的文件,大多数系统文件只允许用户调用,而不允许用户去读或修改它。
- 库文件
- 指由系统提供给用户使用的各种标准子程序库。这类文件允许用户调用,但不允许用户修改。
- 用户文件
- 用户委托文件系统保存的文件。如源程序,目标程序,原始数据等。
- 文件有两种形式的结构:文件的逻辑结构和文件的物理结构。
- 逻辑结构:用户对文件的组织结构
- 物理结构:文件在外存储器上的存储结构
- 物理结构直接影响存储空间的使用和检索文件信息的速度
- 逻辑文件保存到存储介质上的工作由文件系统来做,这样可减轻用户的负担。
文件访问方式
- 连续
- 直接
存储结构
- 顺序结构
- 浪费空间:动态存储分配问题,(外碎片)
- 文件不能增长
- 从逻辑地址映射到物理地址
- 链接结构
- 解决外碎片
- 需要浪费学容量存指针
- 不支持随机存取,想想链表。
- 映射
- 对应逻辑地址的物理块号,加块的大小(偏移),加指针。即可完成映射。
- 可以将块聚集起来,形成簇,减少指针。
- 文件分配表(FAT)
- 一个磁盘只有一张。
- 查FAT就可以实现随机存取,可直接找到对应块,毕竟连续查表比连续查盘快。
- 但是占内存。
- 事实上,打开某个文件时,只需知道该文件所在的盘块号
- 一个文件的信息存放在若干不连续物理块中,系统为每个文件建立一个索引表,并将这些块的块号存放在索引表中
- 一个索引表就是磁盘块地址数组,其中第i个条目指向文件的第i块
- 把所有的指针都一起放在索引块里,即索引分配
还有二级索引
目录
- 内容
- Name(名称)
- Type(类型)
- Address(地址)
- Current length(当前长度)
- Maximum length(最大长度)
- Date last accessed ( for archival )(最后访问时间)
- Date last updated ( for dump )(数据最后更新时间)
- Owner ID( who pays )(所有者ID)
- Protection information ( discuss later)(保护信息)
- 文件控制块FCB
- 用于描述和控制文件的数据结构,它至少要包括文件名和存放文件的盘物理地址
- 文件控制块的有序集合称为文件目录,即一个文件控制块FCB就是一个文件目录项。
- 文件目录是用于检索文件的,它是文件系统实现按名存取的重要手段,它的组织和管理应便于检索和防止冲突
- 目录项:构成文件目录的项目(目录项就是FCB)
- 目录文件:为了实现对文件目录的管理,将文件目录以文件的形式保存在外存,这个文件就叫目录文件
- 目录结构关系到文件存取的性能。
自由(空闲)空间管理
- 磁盘空间有限,如何进行磁盘空间管理?
- 需要记录和维护磁盘的空闲空间
- 创建文件时,搜索空闲空间得到所需空间以分配
- 删除文件时,释放磁盘空间并将其记为空闲空间
- 位图法
- 用一串二进制位反映磁盘空间中分配使用情况.每个物理块对应一位,分配物理块为0,否则为1。
- 占空间
- 空闲块表
- 将所有空闲块记录在一个表中,即空闲块表
- 空闲块链表
- 把所有空闲块链成一个链
文件系统结构和实现
- 文件系统是操作系统中以文件方式管理计算机软件资源的软件和被管理的文件和数据结构(如目录和索引表等)的集合。
- 有一些结构存在内存
I/O 系统
设备
- 设备并不是直接与CPU进行通信,而是与设备控制器通信。
- 每个I/O设备通过设备控制器与计算机的数据总线和地址总线相连接。
- 某些设备(如磁盘设备)有内置的控制器
设备控制器
- 设备控制器处于CPU与设备之间。它接收从CPU发来的命令,并去控制IO设备工作。
- 设备控制器由以下三部分组成:
- 设备控制器与CPU的接口
- 设备控制器与设备的接口
- I/O逻辑
I/O控制方式
首要目标是尽可能的解放CPU
- 程序I/O
- 就是让程序去轮询I/O,是否完成,极其浪费CPU
- 中断驱动
- CPU与I/O设备并行工作
- 在I/O设备输入/输出每个数据的过程中,无须CPU干预
- 仅当输完一个数据时,才需CPU花费极短的时间去做些中断处理。
- 中断的详细过程
- CPU向设备控制器发出一条I/O命令后,立即返回继续执行原来的任务。
- 设备控制器便控制IO设备进行I/O。
- 当设备完成了一个字节数据的I/O时,设备控制器产生一个中断信号。
- CPU检测到中断信号后,进行相应的处理工作。
- 但是中断也有缺点,当有一批数据时,就会频繁中断,影响性能
- 遂引入DMA(Direct Memory Access)
- DMA方式的特点是:
- 数据传输的基本单位是数据块
- 所传输的数据是从设备直接送入内存的.或者相反;
- 整块数据的传送是由DMA控制器完成的
- 比中断更少的需要CPU
缓冲
- 例如一个程序,它时而进行长时间的计算而没有输出,时而又阵发性把输出送到打印机。由于打印机的速度跟不上CPU,而使得CPU长时间的等待。
- 如果设置了缓冲区,程序输出的数据先送到缓冲区暂存,然后由打印机慢慢地输出。则CPU不必等待,可以继续执行程序。实现了CPU与I/O设备之间的并行工作。
- 缓冲池
I/O子系统
设备驱动程序
- 设备驱动程序层的作用是为内核I/O子系统隐藏设备控制器之间的差异
- 是I/O进程与设备控制器之间的通信程序,因为它常以进程的形式存在,故也可以称为设备驱动进程。
- 设备驱动程序实际是处理或操作设备控制器的软件。
- 它们是内核中具有高特权的、驻留内存的底层硬件处理例程。
Spooling技术
- 将独占设备变成共享设备的技术
- 利用多道程序中的一道程序来模拟脱机输入时的外围控制机的功能,把低速I/O设备上的数据传送到高速磁盘上;
- 用另一道程序来模拟脱机输出时外围控制机的功能,把数据从磁盘传送到低速输出设备上;
- 这样,便在主机的直接控制下,实现脱机输入、输出功能。
- 此时的外围操作与CPU对数据的处理同时进行,这种在联机情况下实现的同时外围操作称为SPOOLing (Simultaneous Peripheral Operations On-Line),或称假脱机操作。