操作系统常见问题

下次整理格式,大家随意看看,应该是全网最全的了
一.操作系统概述
什么是操作系统?
1.操作系统是管理计算机硬件和软件的资源的系统程序。本质上是运行在计算机上的软件程序。
2.操作系统是系统资源的管理者,包括内存的管理,网络的管理,设备管理,文件的管理。
3.另外进程之间的调度也是由操作系统来负责。

对几种操作系统的理解?
单道批处理系统,一次只能在内存中放入一个作业独占系统资源,直到运行结束后,下一个作业才能进入内存。当作业进行I/O操作时,CPU只能处于等待。
多道批处理:一次可以在内存中放入多个作业,当一个作业等待I/O处理时,CPU可以调度另外一个作业。作业的执行顺序由一些作业调度算法来决定。另外用户无法干预其运行,交互性很差。
之后出现了分时操作系统,可以实现多用户同时使用计算机。通过对每个用户的进程设置相应的时间片,轮流为不同用户提供服务,由于CPU的处理速度很快,这样看起来每个用户独占整个CPU。由于可以实现多用户交互的向系统提出服务,所以分时操作系统交互性很强。
实时操作系统,一般采用优先级算法,当优先级高的进程在就绪队列时,立即抢占CPU。由于追求安全性和及时性,可以牺牲一定的系统资源。

操作系统被启动的时候会被加载到什么位置?
DSRAM中的系统区。

并发和并行的区别?
1.并发操作是指若干时间再同一时间间隔内发生
2.而并行操作是指在同一时刻发生。
对于进程来说,并行操作需要多处理机才能够完成。而并发操作是靠处理机的调度算法来完成的。另外,在单处理机模式下,同一时刻的进程只能单独占用处理机。但是CPU和外设,CPU和通道,外设和外设直接是可以并行的。

对于一个用户来说可以利用那些方式访问计算机?
命令接口:通过命令行的输入组织和控制计算机系统。
系统调用:通过访管指令使用系统提供的服务
另外,现在大部分操作系统都提供图形接口,本质上是调用了系统调用而实现的功能。

为什么要划分用户态和系统态?
区分内核程序和用户程序,保护操作系统的内核程序。
因为在操作系统中有两种不同的程序,一种为 系统内核 系统程序,一种为系统外层的用户程序。
可以说前者是后者的管理者,像一些系统程序要执行的指令,比如说I/O指令,中断指令,送程序状态字到程序状态字寄存器等等。
用户态切换到内核态的方式有哪些?
系统调用(陷阱):用户态的进程主动要求切换到内核态的一种方式。
故障:比如缺页中断
I/O中断:当外围设备模块准备好的时候,会向CPU发送一个中断信号后,CPU事先会把上下文环境保存在栈中,然后暂停执行下一条执行的指令,转去处理中断信号对应的程序。
在中断发生的时候,CPU就进入了内核态。
核心态到用户态的切换是通过执行一个特权指令,将程序状态字PSW的标志位设置为“用户态”。

举几个用户态下的指令:算数运算指令,取数指令,存数指令。
处于用户态的的指令是可以引发中断的,比如说取数指令,当发生缺页异常的时候,就会发生内中断。
而在CPU在核心态下,可以执行除了访管指令之外的全部指令。
什么是系统调用?
我先说一下用户态和系统态:
用户态(目态):程序只能执行非特权指令,比如说算术运算指令、逻辑运算指令、取数指令和访管指令等。不能直接使用系统资源,也不能进行进程的调度,只能访问这个程序暂时的存储空间。
系统态(管态):程序在管态可以执行大部分非特权指令和特权指令。可以访问操作系统的任何资源和进行进程调度。
系统调用就是用户态的进程主动要求切换到系统态的一种方式。系统调用防止用户态下的程序能够使用特权指令,保证了系统的安全性和稳定性。
常见的系统调用包括:
进程控制。完成进程的创建、撤销、阻塞及唤醒等功能。
进程通信。完成进程之间的消息传递或信号传递等功能。
内存管理。完成内存的分配、回收以及获取作业占用内存区大小及地址等功能。
文件管理。完成文件的读、写、创建及删除等功能。操作系统对文件的管理,是指对文件的逻辑结构,文件的物理结构,文件的内部结构,和不同文件的组织,并不关心文件的内容是谁。
设备管理。完成I/O的请求或释放,以及I/O的控制等功能。
什么时候产生系统调用?
系统调用功能是操作系统向用户程序提供的接口,如果用户程序想要使用系统服务,就必须执行访管指令。这是因为如果用户程序可以直接使用内核态指令,就会威胁到操作系统的安全。比如说用户程序可以直接使用置时钟指令,修改时间片的时间,就会导致其他进程的饥饿,显然这是不可行的。
当一个用户程序执行系统调用命令(此时为高级语言),该指令经过编译器编译之后,会形成若干参数和访管指令(访管指令又被称为陷入指令)

系统调用和库函数的区别?
某些系统调用封装成库函数,来隐藏系统调用的一些细节,使上层进行系统调用更加方便。
比如说read语句从文件中读取数据,就要涉及到系统调用,只不过是封装在了库函数中。
系统调用背后的过程?
举个例子,比如说用户程序中write(“abc”),往文件中写入abc,首先会先传递系统调用的参数,然后经过编译,将高级语言编辑成汇编语言,然后执行陷入指令(发生中断),之后系统调用相关的服务,比如说文件管理。之后给用户程序
什么是访管指令
访管指令是一类机器指令,执行访管指令可以引起访管中断。访管指令不是特权指令,它可在算态下运行,也可在管态下运行。特权指令也是一类机器指令,特权指令只能在管态下执行,不能在算态下执行。系统调用不是机器指令,每个系统调用命令相当于一个函数,该函数实现操作系统提供的一种子功能。用户在编程时也可以使用这些系统调用命令。在系统调用命令中,总是包含一条访管指令,当系统调用执行到访管指令时,就引起访管中断,在进入中断处理程序后便由算态转入管态。在管态下,可以执行特权指令完成操作系统提供的功能。当中断处理程序结束后又从管态返回算态。当用户程序想要操作系统提供服务时,就可以在用户程序中使用系统调用命令,它是操作系统与用户的编程的接口。
中断的类型?
中断广义上可以分为内中断和外中断。
内中断是指信号的来源于CPU内部,与当前执行的指令有关。
外中断是指信号来源于CPU外部,与当前指令执行的指令无关。
其中内中断又分为主动中断和强迫中断。
主动中断主要就是系统调用。其中主动中断又称为陷阱(trap)
强迫中断又可以分为硬件中断和软件中断。
其中硬件中断,比如说缺页中断。
缺页中断又被称为故障。
软件中断比如说整数除零
整数除零又可以称为终止。
外中断:I/O中断

子程序调用和中断的区别?
注意子程序调用和中断的区别,虽然子程序调用和中断都需要保存程序断点(断点就是下一条指令的地址),但是中断处理还需要保存程序状态寄存器(PSW)的内容(PSW中的标志位可以控制管态和目态)。其中程序断点是由中断隐指令进行保存,而由中断服务程序保存通用寄存器和状态寄存器的内容,中断服务程序是操作系统的一部分。

异常和中断的区别?
异常又被称为内中断。比如整数除零,地址越界,缺页异常,陷入指令
中断一般指外中断。比如说I/O中断,表示设备I/O操作完成。时钟中断,表示时间片已到,让处理机去处理计时,启动计时等操作。
时钟中断要处理的信息很多,比如时间片,系统时间,使用CPU的时间,定时器,延时等。
二.进程与线程
对于一个进程实体包含了PCB,共享正文段,数据堆段,数据栈段的内容
其中共享正文段:全局变量,常量
数据堆段:动态内存分配(malloc函数)
数据栈段:实参的传递(临时变量),局部变量
PCB:进程的相关信息

进程和线程的区别?
进程的含义要从两个角度来理解:
1.从进程和程序的区别这个角度:进程就是程序的执行过程。
进程和程序的区别在于:
相比于程序,进程是动态的,有生命周期的。
2.从操作系统调度的角度理解:进程系统进行资源分配和调度的一个独立单位。
第二点的扩充:
进程的运行需要两个条件:
第一个条件是所需的资源,比如内存,数据的磁盘,信号量,文件,I/O设备和CPU时间等。
第二个条件是操作系统进行调度:比如PCB的初始化,包括标识符(就是给进程编号,能识别是哪一个进程),初始化处理机状态信息(当处理机处于执行时,保存在CPU的寄存器中,当上下文切换的时候保存当前环境到PCB中),初始化进程的调度信息(给进程设置状态,比如就绪状态,或者优先级的设置),初始化进程控制信息(程序段和数据段的地址,进程同步和通信的机制,资源清单,链接指针)

线程的含义?
线程是包含在进程之中,并且是操作系统可以调度的最小单位。
引入线程的目的就是为了减少程序在并发执行的时候所付出的时间开销,提高并发性能。
线程只是进程的一部分,比如运行QQ时作为一个进程,而聊天,传文件,看相应的新闻可以作为线程,聊天,传文件,看新闻之间的线程切换是不需要进程的切换的。但是不同进程之间的线程切换是需要切换进程的,比如聊天的时候去执行另一个进程打开网页。

在多对一模式当中,如果一个内核进程,它映射到用户级后有多个线程,则这些线程的切换
不需要在内核切换进程,即不需要内核支持。
另外,在多对一模型中,一个用户有多少线程对操作系统完全是透明的,比如如果一个用户线程被阻塞,则整个进程就会被阻塞。

进程有哪几种状态?
我们一般把进程大致分为 5 种状态,这一点和线程很像!
创建状态(new) :进程正在被创建,操作系统为其分配资源和初始化PCB
就绪状态(ready) :进程已处于准备运行状态,即进程获得了除了处理器之外的一切所需资源,一旦得到处理器资源(处理器分配的时间片)即可运行。
运行状态(running) :进程正在处理器上上运行(单核 CPU 下任意时刻只有一个进程处于运行状态)。
阻塞状态(waiting) :因为某些事件而暂时不能运行时的进程,即使CPU空闲,也不能运行
结束状态(terminated) :进程从系统中撤销,操作系统会回收该进程的资源,撤销PCB
运行态->阻塞态 进程自身可以决定(执行P原语 -阻塞原语),I/O请求(等待其他事件)
注意访问磁盘,属于I/O操作 申请内存失败 申请临界资源失败 (主动行为)
运行态->就绪态 时间片用完(主动),就绪队列出现了优先级更高的进程(被动)
就绪->运行 处理机调度 (被动)
阻塞->就绪 I/O操作结束 其他进程退出临界区 (被动行为,由相关进程决定)

进程间的通信常见的的有哪几种方式呢?
由于在硬件地址保护机制下,不同的进程只能访问自己的内存地址空间,如果进程之间需要消息的传递,就需要进程通信来完成。比如说进程A需要先写往共享缓冲区写入数据,进程B才能读取数据,其先后的执行顺序需要进程通信来协调,以此完成进程的同步。

共享内存(Shared memory) :使得多个进程可以访问同一块内存空间,不同进程可以及时看到对方进程中对共享内存中数据的更新。而对共享内存空间需要互斥的进行,这种方式需要依靠某种同步操作,如互斥锁和信号量等。
对于共享内存方式,又可以分为基于数据结构的共享和基于存储区的共享,前者需要限定共享空间只能传递固定的数据结构的数据,比如只能放长度为10的数组。这种共享方式速度慢,有格式限制,是一种低级的通信。
后者不限制数据的形式,存放的位置,一切都由进程自己来控制。速度更快,是一种高级通信方式。
管道(Pipe)就是一个可以读写进程的共享文件。管道是采用半双工通信,即同一时间段内只能进行单向通信,如果要实现双向同时通信,需要设置两个管道。
管道的访问也是互斥的,而且管道中的字符流只有写满之后才能读,全部读完之后才能继续写。
消息通信 :进程之间直接传递格式化消息。消息的传递是通过发送原语和接收原语来进行。每个消息包含消息头和消息体,消息头就包含了发送进程的ID,接收进程的ID,消息的类型和长度等信息。类似于报文。
对于消息传递可以分为消息队列和邮箱两种形式。消息队列就是直接把消息挂到接收方的消息队列上。而邮箱就是经过一个中介,发送方先发送消息到邮箱,接收方再从邮箱中取出数据。

套接字(Sockets) : 此方法主要用于在客户端和服务器之间通过网络进行通信。套接字是支持 TCP/IP 的网络通信的基本操作单元,可以看做是不同主机之间的进程进行双向通信的端点,用套接字中的相关函数来完成通信过程。

不同的进程之间存在什么关系?
进程之间存在互斥和同步的制约关系。
同步:当有多个进程的时候,各个进程需要协调其执行顺序而等待产生的制约关系。
互斥:多个进程申请临界区资源的时候,只能有一个进程使用临界区资源,其他进程必须等待。也就是各个进程对临界区的资源的访问是互斥的。

对于可改变优先级进程的时机?
时间片用完时降低优先级,让其他进程执行
进程长期处于就绪队列,可通过提高优先级,防止其饥饿
进程刚完成I/O操作,应该从阻塞态唤醒并提高其优先级,让其尽快处理I/O结果

父进程创建子进程和主程序调用子程序的区别?
父进程创建子进程后,父进程和字进程并发执行。
而主程序调用子程序的时候,主程序需要暂停,转而执行子程序,直到子程序返回相关参数,主程序才能够进程,有明显的先后执行顺序。
多线程,多用户,多任务区别?
首先说一下什么是多用户,指一台主机可以有多个终端,不同的终端可以同时的操作一个主机。比如说一台Linux服务器就是多用户的,不同的用户在自己的权限下可以完成不同的操作,实现多用户并行的工作。
而多任务是针对操作系统而言,是一个用户可以一次运行或者提交多个作业。
而多线程是针对一个程序而言的,代表一个程序可以同时执行的线程个数,每个线程完成不同的工作

三.处理机调度
处理机调度的目的是为了什么?
如果没有处理机的调度,当前执行的进程必须执行完毕后,才能将处理机分配给下一个进程。
而在实际情况中,进程可能会需要某些I/O设备的输入,由于外设的速度和处理机的速度差别很大,如果让当前进程一直等待I/O的结果,就会浪费CPU的资源。而此时,如果可以通过处理机的调度来实现将当前CPU暂时调度给其他进程使用,就会提高处理机的利用率。而这种进程之间的切换,是由中断的来实现的。
什么是进程同步?
在多道程序当中,进程是并发执行的,不同的进程执行具有异步性,为了协调各个进程的执行顺序就引入了进程同步。
为了防止两个进程同时进入临界区,同步机制应该遵循什么原则?
空闲让进,忙则等待
让权等待:当进程进入临界区被拒绝后,立即释放处理器,防止忙等
有限等待
你知道操作系统中进程的调度算法有哪些吗?
先到先服务(FCFS)调度算法 : 从就绪队列中选择一个最先进入该队列的进程为之分配资源。
短作业优先(SJF)的调度算法 : 从就绪队列中选出一个估计运行时间最短的进程为之分配资源。
HRRN(Highest Resonse Ratio Next )高响应比算法:响应比越高的进程/作业先得到服务
时间片轮转调度算法(Round-Robin):各个进程轮流执行一个时间片,当时间片用完则进入就绪队列,CPU调度下一个进程
优先级调度 : 为每个流程分配优先级,首先执行具有最高优先级的进程,依此类推。具有相同优先级的进程以 FCFS 方式执行。可以根据内存要求,时间要求或任何其他资源要求来确定优先级。
多级反馈队列调度算法 :设置多级就绪队列,各级队列优先级从高到低,时间片从小到大。
新进程进入第1级别队列,每一级别队列按照FCFS原则排队等待时间片。时间片用完则进入下一级别队列,只有高级别队列为空的时候,才可以运行更低级别队列。

三级调度?
高级调度(作业调度)
从后备队列将合适的作业调入内存,并且为其创建进程,分配资源,并放入就绪队列
中级调度(内存调度)
从挂起队列中选择何使得进程将其数据调回内存(这里的数据主要是进程映像,也可以离皆为程序段,而不是PCB)
低级调度
从就绪队列中选择一个进程分配处理机

四.死锁
什么是死锁?
由于多个进程之间互相申请对方的资源,造成各个进程之间相互等待,如果没有外力作用,将一值等待下去,造成死锁。
什么是临界区和临界资源?两个的区别在哪里?
临界区仅仅指访问临界资源的那段代码,假如有5个进程需要访问一个共享变量A,此时就会有5个临界区,即5个相应访问共享变量A的代码段。但同一时刻只能有一个进程进入临界区,只有进入临界区的进程才能申请相应的临界资源。
而临界资源是指一次只允许一个进程使用的临共享资源,比如说硬件上有打印机,软件上有共享变量,消息队列,共享缓冲区等

临界资源必须满足哪两个条件?
互斥和共享。即临界资源要互斥的使用,并且不同的时间是可以共享使用的。

什么是信号量?信号量的表示有什么含义?
信号量就是一个特殊的整型变量,只有PV原语和初始化操作才能改变其值。
信号量分为互斥量和资源量。对于互斥量来说,初始值为1代表可以有一个进程进入。互斥量为0代表临界区已经有一个进程进入。互斥量小于0,代表已经有一个进程访问临界区,且其绝对值代表临界区外等待的进程个数。资源量同理。

如果处于临界区的进程由于申请I/O操作而中断,其他进程可以进入临界区吗?
不能进入临界区,当临界区进程发生I/O操作被阻塞的时候,可以让出CPU给其他进程,但是其他进程不得访问临界区资源。 除非个该临界区的“锁”上阻塞。
什么是PV原语?
首先,原语是指不可分割的操作,其执行具有原子性,不可以被打断。
P操作代表wait,表示等待某一资源直到可以使用。等待的过程中进程会进入阻塞状态。
V代表wake,表示唤醒某一资源。被阻塞的进程会进入就绪状态。

管程的含义?
管程通过一个共享数据结构抽象的表示各种硬件和软件资源的个数,
并且利用一组过程来对共享数据结构进行资源的申请,释放。
并且可以根据条件变量来对进程进行阻塞或者唤醒。
一下几点可以更好的理解管程:
管程把对共享资源的操作给封装了。进程通过调用管程内的过程来访问共享资源。
每次只能有一个进程进入管程,实现互斥。

为什么引入管程?
解决临界区分散所带来的控制和管理问题。如果没有管程,对临界区的各种操作分布在不同的进程之中,而如果用户程序不正确的使用PV原语就会出错。而管程的目的就是把这些对临界区的操作封装起来,这样用户想要访问临界区,就可以调用管程的过程来实现,没有必要自己再创建临界区的代码。

PV原语和管程中的signal/wait操作一样吗,有什么区别?
不一样,singal/wait操作是针对管程中的条件变量的,如果条件变量(条件变量代表了其阻塞原因)不存在,则操作没有任何意义。
并且singal/wait仅单纯的代表唤醒和阻塞,没有值。
而PV原语是由值的,不同的值有不同的含义。

什么是可重入编码?
允许多个进程同时访问的代码,其代码不可修改,所以无论执行多少次,结果都是相同的。
因此可重入代码常用于共享程序段。

几个算法的题和类型需要找时间看

为什么会产生死锁?产生死锁的条件?
空间上看:是资源分配不均造成的死锁,比如说有个9个同类资源,此时有3个进程申请这个资源,且必须要申请4个资源才能够执行。如果按照每个进程都分配3个资源的话,所有
的进程都不能执行,造成死锁。
时间上看:是由于进程的推进顺序有问题,比如说进程A占有一个资源,同时申请进程B的资源,就会造成进程A进入阻塞,但同时也不释放自己的资源。

系统资源不足是造成产生死锁的原因吗?
系统资源不足不一定会导致死锁,但一定会导致产生饥饿,比如有三台打印机,而一个进程的运行需要四台,则这个进程就会产生饥饿。

死锁产生的条件?
互斥条件:在一段时间内,临界资源只能分配给一个进程
不可剥夺条件:临界资源不可以抢占
请求并保持:已经获得至少一个资源的进程去申请进程的资源,导致请求的进程阻塞,并且不释放自己的资源。
循环等待条件:存在一条进程的循环等待链,每个进程已获得了资源,同时申请链中下一个进程所占有的资源。

如何处理死锁?
死锁的预防(资源分配之前):破坏循环条件中的一个。
1.破坏不可剥夺:所谓破坏不可剥夺,不是指其他进程可以抢占临界资源。而是一旦有其他进程要申请该进程的临界资源的时候,立即主动放弃该资源。可能造成该进程饥饿。
2.破坏请求并保持条件:既然进程因为请求其他资源导致阻塞,那么可以采用一次把所有资源都申请的方法。但是存在两个问题,第一个问题在于某些资源被其他进程所占有,可能会导致该进程饥饿。第二个问题在于,即使获得了某些资源,但是往往使用频率不高或者根本不需要,导致资源利用率降低。
3.破坏循环等待:给系统资源编号,每个进程只能按照编号递增的顺序申请资源,比如要申请资源1,下一次该进程就只能申请资源2。但是缺点在于资源的编号是固定的,如果此时增加一个资源设备,就会将资源重新编号。或者会出现使用资源的顺序和资源编号的顺序不同,也有可能造成申请了多余的资源。

死锁的避免(资源分配之中):银行家算法,是在资源分配之中进程预防,防止系统进入不安全状态。(还需要再看)

死锁的检测(资源分配之后):资源分配图+死锁定理
死锁的解除:资源剥夺,即挂起某些产生死锁的进程,释放其资源给其他进程。
进程撤销:强制撤销某些进程并且释放其资源。
进程回退:让一个或者多个进程回退到足以回避死锁的程度。

简述一下什么是资源分配图和死锁定理?
资源分配图就是用框代表一类资源,框中的圆代表资源数量。用圆代表进程。如果有一条边从框指向圆代表分配资源给一个进程。从圆指向框代表该进程申请一个资源。

死锁定理就是:在资源分配图中如果能找到既不阻塞又不孤立的结点,则可以把该结点的所有边消去。从而唤醒某些被阻塞的结点,如果被唤醒的结点依然满足不阻塞且不孤立,则重复完成第一步的操作,直到所有边都消去。
造成死锁要满足两个条件:出现了环路且每种资源只有一个,即形成了循环等待链。
如果仅仅出现环路,不一定产生死锁,因为可能每种资源很多。
如果没有环路,这就不满足死锁的第四个循环等待条件,一定不会产生死锁。

死锁和不安全状态的关系是什么?
死锁一定会导致不安全状态,但不安全状态不一定是死锁。

五.内存管理
内存管理主要做什么?
1.操作系统的内存管理主要负责内存的分配和回收。

2.另外地址转换也就是将逻辑地址转换成相应的物理地址等功能也是操作系统内存管理做的事情。
3.内存空间的扩充。虚拟存储器和自动覆盖技术
4.存储保护。各道作业在自己的存储器运行,互相不干扰。

讲一下将用户程序变为内存中可执行程序的过程?
编译-链接-装入
以C语言的执行为例子:
C程序首先经过预处理—>编译---->汇编—>链接
在链接之前会生成需要main.o,file.o,file2.o文件这些文件就是编译后形成的目标模块。
而链接的过程就是将这些目标模块与库文件链接为一个可执行文件,并将地址重新组织。
指令放在程序段,数据放在数据段
指令中没有任何数据,只有操作码和地址码

比如说00000011这个地址是逻辑地址而不是物理地址,如果是物理地址的话就是绝对装入。

讲一下动态分区分配算法?
首先,对于动态分配算法我们需要相应的动态分配数据结构为分配提供依据。
一般来说,动态分区分配的数据结构有空闲分区表,和空闲分区链两种。
而为了使得作业能够更高效的存入内存当中,我们可以根据相应的动态分区算法来从表或者链中选中某一个部分分配给作业。
动态分区分配算法一般来说可以分为以下几种,我以空闲分区链来进行举例。
第一种是首次适应算法
描述的过程:首先所有的空闲分区链会按照地址递增的顺序进行链接。当进行内存分配的时候,会从链头顺序的搜索整个链表。然后按照进程的大小,从该分区中划去一块内存空间给进程,而剩下的空闲分区仍然保留在空闲链中。
优点在于:优先利用低地址部分的空闲分区,从而保留了大地址部分的空闲分区,为以后的大进程的内存分配创造了条件。
缺点在于:由于低地址被不断花费,会产生大量的很小的外部碎片。
每次查找都是从低地址还是查找,增加了查找的开销。

第二种是最佳适应算法
所有的空闲分区按照内存空间的大小通过空闲分区链或者空闲分区表进行递增排序。使得每次给进程分配一个能够满足且空间最小的空闲分区。
优点在于:可以更好的保留高地址部分的大分区给更大的作业或者进程。
缺点在于:首次适应算法每次划分剩余下来的空闲区也总是最小的,可能会产生大量的外部碎片。
第三个是最坏适应算法
将所有按照空闲分区按照内存空间的大小进行递减排序。每次选择一个最大的空闲分区从中分割一部分存储空间给作业或者进程。
优点在于:可以减少产生小碎片
缺点在于:大分区容易被用完,导致所占空间大的作业或者进程无法进行分配。
第四种是邻近适应算法,将空闲分区按照地址递增的顺序进行链接,并可以形成一个循环链表的形式。
优点在于:不需要每次进行空间划分的时候,重新从链头进行查找,而是从上次查找的空闲分区的下一个空闲分区进行查找。而且可以使得内存中的空闲分区分布更加均匀。
缺点在于:有可能使高地址的大分区被用完。

逻辑地址到物理地址的转换?
比如在 C 语言中,指针里面存储的数值就可以理解成为内存里的一个地址,这个地址也就是我们说的逻辑地址,逻辑地址由操作系统决定。物理地址指的是真实物理内存中地址,更具体一点来说就是内存地址寄存器中的地址。物理地址是内存单元真正的地址。

什么是覆盖技术?
覆盖技术一种用与单一连续分配的古老的分配方式,通过将内存划分为覆盖区和固定区。其中固定区用来存放常用的程序,其余部分段。并且覆盖区存放即将要访问的段,其他段放入外存,需要的时候再调入覆盖区。

可变分区分配中,可能需要将主存空间与相应的空闲分区合并,为此必须修改空闲分区表,请分析一下回收内存是空闲分区表的情况?
首先,只有可变分区分配才需要考虑这个问题,也就是动态分区分配,对于固定分区分配是不存在这个问题的。如果一个主存空间在回收之前有上相邻存储区和下相邻存储区,在回收主存空间的时候空闲分区数会减一。如果既有上相邻存储区和下相邻存储区,空闲分区数就会加一。只有上或下的话,空闲分区数不变。

什么是交换技术?进程处于什么状态下不能进行交换?
交换技术是指将处于等待状态下的进程换出到外存当中,而将准备好竞争CPU资源的进程从外存换入内存。
比如说但某个进程的时间片用完之后可以暂时将其换出到外存,而将另一个进程换入内存。同时CPU分配给已经在内存在的进程。
当进程处于I/O操作的时候,不能进行换出。可能会导致I/O的数据区被其他进程占用,导致数据出错。可以通过开辟一个I/O缓冲区专门用来进行I/O操作,这样即使该进程换出到外存,I/O缓冲区也不会被其他进程占用。

覆盖技术和虚拟存储技术有何本质不同?交换技术与虚拟存储技术的调入/调出技术有何相同和不同之处?
覆盖技术和虚拟存储技术:
不同点:覆盖程序程序段的大小收到内存大小限制,而虚存中的程序大小受到地址总线宽度,也就是寻址范围的限制
覆盖程序段由程序员设计,各个覆盖具有相对独立性。虚拟存储技术对用户程序段没有这种要求。
交换技术和虚拟存储技术:
相同点:都是在内存和外存中交换信息
区别:交换技术交换的是整个进程,而虚拟存储器调入/调出的是页面或者分段,更加灵活。
交换技术不允许进程的大小比内存大,而虚拟存储器的大小依赖于地址总线的宽度。

如何进程内存的保护?
1.设置上下限寄存器。CPU中有一个上下限寄存器来存储作业在内存中的上下界。每当CPU访存的时候都需要进行越界判断
2.重定位寄存器和界地址寄存器。
其中重定位寄存器是最小的物理地址值。界地址寄存器是逻辑地址的最大值。
CPU进程访存是,先与界地址寄存器进行判断访存地址是否越界,如果没有越界则加上重定位寄存器的值生成最终的物理地址。

为什么要引入”紧凑技术”,紧凑技术的缺点是什么?
由于连续分配方式,一个用户程序或者系统会被分配到连续的地址空间当中。在进行分配的过程中,内存空间会被划分为一个个小的分区分配给相应的进程或者作业,但也会留下大量的容量较小的空闲分区。这样当有一个大进程进行内存空间申请的时候,即使内存中剩下的空闲分区总和大于进程所需要的的内存空间大小,也无法进行分配。所以引入了”紧凑技术”。
紧凑是移动内存中的作业,使他们变成相邻的。这样内存中剩下的需要小的空闲分区就会拼接成一个大的空闲分区供大作业进行分配。
但是每一次使用”紧凑技术”,相应的作业或者进程在内存中的位置就发生了改变,即相应的物理地址需要改变,这是一件十分影响系统效率的事情。

动态重定位的过程是什么?
正是由于紧凑技术需要移动大量的数据,改动各个进程或者作业的物理位置。所以我们在将逻辑地址转换为物理地址的过程采用动态重定位方式。
动态重定位的过程实际上就是在执行时将指令要访问的逻辑地址转化为物理地址的过程。
在一个作业装入内存的时候仍然保留的是逻辑地址。而将逻辑地址转化为物理地址的过程需要到指令运行的时候才进行。这时候需要一个重定位寄存器保存当前程序在内存中的起始位置也就是基址,而真正访问的时候需要将重定位寄存器中的基址与逻辑地址相加得到物理地址。
而通过紧凑或者对换的时候,程序的位置可能会发生改变。这时候只需要修改重定位寄存器的地址为当前程序的初始位置即可。

如何解决碎片问题?
1.设置门限值
当划分空闲分区的时候,如果剩余的部门小于门限值,则将此空闲分区全部分给用户。
2.紧凑’技术’
3.采用离散分配方式

为什么要引入分页存储,介绍一下分页存储方式?
由于连续分配方式,一个进程必须连续的分配到内存单元当中。
但是如果可以把几个进程分成不同的页,离散的装入到不同的分区,就可以充分的利用内存。
(连续分配方式和离散分配方式的区别在于是否对进程进行分段或者分页)
分页存储方式就是把内存分为不同的页框,页框的大小必须是相同的。
然后把进程分为与页框大小相同的页面
(但是进程的最后一个页面有可能没有一个页框的大小这么大,所以不能把页框分配的太大,这样可能产生比较大的内部碎片。)
而分页存储的关键也是将页面中指令或者数据的逻辑地址转化为内存中的物理地址。
只不过由于每一个指令都存在固定的页面中,我们需要知道页面在内存中的起始位置和内存单元在页内的偏移量。
为了能得到每个页面在内存中的起始位置,就需要为每一个进程设置一个页表。
(页表一般是放在内 存当中,而在进程未被调用的是,页表在内存中的起始位置和页表的长度放在PCB当中,只有进程被调度的时候,才将这些信息放到页表寄存器当中)
这样用户在输入一个逻辑地址的时候,首先会根据逻辑地址的高位存储的页号与页表寄寄存器存入的页表长度进行比较,如果出现越界就会产生越界中断。
否则则根据页表的起始位置去找到相应的页表项的地址(页表项的地址=页表的起始位置+也P*页表项的长度)。页表记录了该页号对应在内存中的块号。这样通过块号和逻辑地址的地位表示的页内偏移量,便能够完成对于某个数据的逻辑地址向物理地址的变化。
在页式存储管理中选择页面的大小,需要考虑哪些因素?
如果页面过大,好处是页表比较少,内部碎片变大。
如果页面过小,好处是减少由内部变小了,但是页表项变多,因此页表变大,所需的内存空间也就越大。
为什么要引入快表?引入快表后的地址转换过程发生了哪些改变?
由于引入了页表,这样我们每一次进行地址转换的时候,需要两次访存,第一次是访存页表,第二次是访存相应的数据。但是由于访问内存会消耗CPU的处理速度。所以为了减少访存的次数,我们利用一个高速缓冲寄存器,也称为快表来存放页号和块号之间的映射关系。

引入了快表之后,首先CPU给出了一个逻辑地址,地址转换机构会将页号送入快表中,与表中的的所有的页号进行比较,若找到相匹配的页号,直接根据快表中的页号所对应的块号和逻辑地址中的页内偏移量得到物理地址。如果没有找到,则还是从页表中去找相应的块号,并且把当前页表项送入到快表当中。
(一条指令是存在内存中一个页框中的某一部分,所以还需要页内地址)
为什么要引入多级页表?
因为页表本身也是存在内存当中的,如果页表过大的话,可能在内存当中无法找到相应的内存空间存这个页表。
而且实际上进程在运行时只是需要访问几个特定的页表项,所以没有必要让整个页表都存在内存当中。(虚存技术)
所以针对单级页表以上问题,我们可以对页表本身也采用离散分配的方法,并且把不需要的页表项放入磁盘当中。
首先把一个页表可以分为多个页表,每个页表的大小不能超过一个页面。除此之外还需要一个顶级页表用来存储每个页表项分页的起始地址。二级页表记录了进程的某一页在内存中的物理块号,可以利用顶级页表和二级页表实现逻辑地址到物理地址的映射。
但多级页表不仅不会加快地址的变换速度,还会减慢地址的变换速度,因为需要查表多次访存。

为什么要引入段式存储方式?引入段式后的地址转化的过程发生了哪些改变?
引入分段的目的主要是为了满足用户在编程和使用上的要求。
1.由于一个程序有若干个段组成,每个段都有自己的特点和用途。
比如说程序段设置只读,而数据段设置为可写,这样分段处理有利于信息保护。
2.汇编指令的时候,按照段名:段内地址十分方便程序员编程,也更加直观。

正是由于每个段有不同的特点,所以每个段的大小也不同。
所以我们需要建立一个段表去记录相应的段号,段长和段基址。每个进程都有自己的段表,而且段表一般来说是放在内存当中的。当调用进程的时候,会把当前进程的段表始址和段表长度放入一个段表寄存器当中。
在进行逻辑地址转换的时候,首先系统会将逻辑地址中的段号与段表长度进行对比,判断当前的段号是否越界,如果发生越界,就会产生越界中断(内中断)。如果没有越界,则根据段号去段表中查找相应的段标项。此时还需要将段内地址与当前段标项记录的段长进行比较,判断是否超越段长,如果超过段长,还是会发生越界中断。这样根据段标项记录的当前段的段基址与段内地址相加就得到了物理地址。
(这是由于段内地址的位数是固定的,而段长是可以改变的,段内地址完全可能大于段长。)

请说一下分段和分页的区别?
1.页的大小是固定不变的,而每个段的大小是不同的,取决于当前用户编写的程序。
2.分页的目的是为了提高内存的利用率,而分段的目的是为了满足用户需求。
3.页仅仅是一个物理单位,因为页就是代表内存当中的一个块而已。而段是逻辑单位,他是可以根据用户的需求进行划分的,本身就是具有信息的。比如说定义一个堆栈段,一个程序段。但是却不存在什么程序页或者堆栈页吧。所以说分段是用户编程的时候决定的。
4.分段比分页可以更好的实现信息的共享和保护,因为我们可以把一个可以共享的信息单独作为一个段,但是分页的话共享的数据可能占据多个页。
(其他:起始分页存储比分段此处更能很好的解决碎片问题,因为页的大小相同,内存分配的时候也更加方便。但是段的大小不同,比如当内存最大空闲区的大小为10K,但是当前我定义的段就是需要11K怎么办,所以分段相比于分页会产生更多的碎片。)
5.分页的地址空间是一维的,而分段是二维的,因为分段既要给出段名还需要给出段长。
6.页式会产生内存碎片,而段式只会产生外部碎片

如两个进程共享一个段的时候会发生什么?
由于两个进程的逻辑段号可能是不同的,所以依然需要为每个进程创建自己的段表。但是在段表的映射关系上,不同的逻辑段号一定会映射到相同的物理块号上。因为共享段式唯一的。

为什么引入段页式,段页式的地址转换过程是什么样的?
之所以引入段页式,就是因为页式的内存利用率更高,段式能更好的的满足用户的需求。所以将两者的长度结合一下形成了段页式存管理模式。
在段页式存储过程中,既需要段表也需要页表。但此时段表更多的可以作为页表的一个索引,因为段表记录的段号,页表的大小和页表的实址。而页表中存的是页号和块号的映射关系。
首先根据逻辑地址得到段号与段寄存器的段表长度进行比较,判断是否发生越界中断。没有的话根据相应的段号找到段表中相应的段标项,然后检查逻辑地址中记录的页号是否与当前的段标项记录的页表长度发生越界中断。没有的话则根据当前段标项的页表实址找到相应的页表。并且根据页号找到页表中的页表项,并根据页表项记录的块号与页内偏移量进行相加得到物理地址。
如果不引入快表的,需要三次访存。

采用段式和页式存数哪一个可提供给用户的物理空间更大?
这个是不能确定的,由于段表和页表大部分是存储在内存当中的。所以提供给用户的内存空间为整个内存空间减去段表和页表的大小。而页表和段表的大小是不固定的。
虽然页表是存在于内存当中,但是页表的起始位置是存放在页表基址寄存器当中的,这样是为了加快地址的转换。

访问主存时,以什么为单位?
以字节或者字为单位。虽然内存分配的时候可以分段或者分页,但是访问的时候最后还是访问到段内或者页内的偏移地址,也就是一个字或者字节。

什么是局部性原理?什么是虚拟存储器?
局部性原理又分为时间布局性和空间局部性。
所谓时间局部性是指当前被访问的指令和数据将在不久后被再次访问。
空间局部性是当程序访问了某个存储单元后,其周围的存储单位在不久后也将被访问。
这是由于程序中存在的大量的循环语句,并且程序的执行大部分都是顺序的,
一个程序调用过程的深度不超过5,并且程序中对数据结构的操作只是局限在很小的一个范围里。
正是由于局部性原理的发现,所以才引入了虚拟存储器的概念。
所谓虚拟存储器就是指我们把暂时不用页或者段先放到外存中暂存,而把当前需要执行的页和段调入的内存当中。如果发现内存没有需要的页或者段,将会发成缺页(段)中断。此时再从外存中把需要的页面调入。如果发现此时的页面已满,操作系统还需要利用页面置换功能,把内存中的某些页调回到外存当中,之后再把需要的页或者段调入内存。
这样内存容量看起来比内存本身大得多。

虚拟内存为什么只能建立在离散分配的内存管理上?
由于连续分配的特点:会将一部分内存空间都处于暂时或者”永久”的空闲状态,造成内存空间的浪费。另外由于其地址是连续的,当进行换入换出内存的时候,逻辑上也不方便扩大内存容量。
虚拟内存技术如何实现?
虚拟内存的实现需要建立在离散分配的内存管理方式的基础上。
虚拟内存的实现有以下三种方式:
请求分页存储管理 :建立在分页管理之上,为了支持虚拟存储器功能而增加了请求调页功能和页面置换功能。请求分页是目前最常用的一种实现虚拟存储器的方法。请求分页存储管理系统中,在作业开始运行之前,仅装入当前要执行的部分段即可运行。假如在作业运行的过程中发现要访问的页面不在内存,则由处理器通知操作系统按照对应的页面置换算法将相应的页面调入到主存,同时操作系统也可以将暂时不用的页面置换到外存中。
请求分段存储管理 :建立在分段存储管理之上,增加了请求调段功能、分段置换功能。请求分段储存管理方式就如同请求分页储存管理方式一样,在作业开始运行之前,仅装入当前要执行的部分段即可运行;在执行过程中,可使用请求调入中断动态装入要访问但又不在内存的程序段;当内存空间已满,而又需要装入新的段时,根据置换功能适当调出某个段,以便腾出空间而装入新的段。
请求段页式存储管理

在虚拟内存系统中,只要磁盘空间足够大,作业就能拥有任意大的编址空间吗?
不一定,编址空间的大小取决于硬件的访存能力,说白了就是地址总线的宽度。
地址总线越宽,寻址的范围就越大。

请求分页和分页存储有什么区别?
分页存储的目的更多是是实现内存管理,改进连续存储的缺点。而请求分页的目的更多是如何实现虚存技术。
在请求分页中,当访问的信息不再内存中的时候,会发生缺页中断,操作系统会将消息从外存调入内存,然后执行。如果内存空间不够,还会进行页面置换。
所以请求分页在页表中做了一些修改,比如说
为了标识某个页面是否调入内存,需要设置一个状态位。
在页面置换的时候,还要看某个页面是否已经修改过,如果没有修改过就没有必要写会外存,如果修改过,为了保持数据的一致性还需要重新写入外存。因此需要设置修改位。
在进行页面置换的时候,某些页面置换算法可能会根据最近访问次数来进行置换,因为还需要设置一个访问字段。
如果某个页面在外存,还需要记录外存的地址。
除了对页表修改外,还需要有一个缺页中断机构,主要是根据状态位判断页是否在内存当中,如果不在则需要产生一个缺页中断,将页面从外存调入内存当中。如果此时内存已经满了,还需要设置相应的页面置换算法。

如果页面尺寸增加一倍且可容纳的最大页数不变,则程序顺序执行产生的缺页中断次数会增肌还是减少?
首先,页面的大小和页帧的大小是一一对应的,一个进程所占内存空间的大小是有限的,如果页面尺寸增加一倍,则一个进程所需的页面必然减少,因此相应的页帧数目也必然减少,从而缺页中断的次数也会跟着减少。

有哪些页面置换算法?
页面置换算法主要是用于发生缺页中断时,当从外存调入内存某些页或者段的时候发现内存已满,需要用页面置换算法把某些页和段调出去。
常用的页面置换算法有
最佳置换算法:选择淘汰的页面是最长时间不会被访问的页面。
因为需要提前预支哪个页面是最长时间是不访问的,这只是一种理想化的算法,不可能实现。
先进先出算法:选择淘汰的页面是最先进入内存的页面。
缺点:算法性能差
最近最久未使用算法(LRU):将最近最长时间未访问的页面调出。该算法的实现是为每一个页面设置一个访问字段,访问字段记录的每个页面自上次访问以来的时间t,选择t最长的那个页面进行淘汰。
性能较好。
需要注意的是,LRU算法需要对页面的使用页面次序排序,需要硬件支持,开销比较大。
CLOCK算法:为每个页面设置一个访问位,将内存中所有的页面通过指针形成一个循环队列,当某个页面被访问是,访问为设置为1。然后轮流的检查每一个页的访问位,如果为0,就将其换出,1的话重新设置为0,暂时不换出。其基本思想就是先把没有被访问过的页面优先换出。
C-CLOCK算法(最近未用算法):该算法是为每一个页面设置一个使用位,轮询的访问各个页面。
对于使用位为1的页面将其置为0。
对于扫描到的第一个使用位为0的页面选择淘汰。
如果对C-CLOCK算法进行改进,因为被页面置换的算法,如果在内存当中没有被修改是完全没有必要写会外存的。只有被淘汰的页面被修改过才需要写会外存。
因此为了减少I/O操作,C-CLOCK算法增加了一个修改位,优先淘汰即被修改过,也被访问过的页面。
实现简单,性能不错。

假如有m个物理块初始时全空,并且一个进程有n个不同的页号,缺页次数不会少于多少?
因为初始的时候进行页面访问必然发生缺页,因为内存中初始物理块为空,所以缺页次数不会少于n次。

在引入虚拟存储器是,作业在运行时可以不在内存中吗?
作业在运行前不必全部装入内存,且在运行过程中也不一定装入内存。这也是请求分页和基本分页的区别。对于基本分页,在一个程序运行前必须将作业全部装入内存当中。

什么是Belady异常?
在使用先进先出的页面置换算法时,随着所分配的内存块的增多,发生缺页的次数有可能反而越来越多。
之所以会产生Belady异常,是因为先进先出算法没有考虑进程实际运行的规定,因为先进入的页或者段也有可能经常被访问。
但是注意一点,Belady异常不是一定会发生的,比如说页帧数目为2的时候,页面的顺序1,2,3,1,2,3此时会发生6次缺页中断,如果页帧数为3的时候,只会发生3次缺页中断,此时就没有发生Belady异常。所以分析是否发生Belady异常还是需要讨论具体的访问页面的顺序。

什么是”抖动”现象?如何解决抖动?
“抖动”现象是指页面频繁的换入内存和换出外存。
造成抖动的原因是进程频繁访问的页面数目高于可用的物理块数。
另一个原因可能是页面置换算法的选择不当。
对于解决抖动可以采取可变分配局部置换策略,这样的话主要是减少对其他进程的影响,因为局部置换只能在该进程的内存空间里进行置换。或者暂停某些进程,这样就能有更多的内存空间分配给缺页率高的进程。
或者替换一个置换算法。
可以采用工作集算法,就是当从外存调入内存的时候会检查内存的驻留集,如果驻留集足够大,便可以从外存调入内存当中。如果驻留集不够,即缺页率偏高,则为进程增加物理块。
归根结底还是增加物理块的个数。

驻留集和工作集的区别?
驻留集是请求分页管理中给进程分配的物理块的集合。
而工作集是在一段时间内,进程要访问的内存块号的集合。

为什么引入工作集?
引入工作集后,可以让OS跟着每一个进程的工作集,如果发现某些页面不在工作集当中,可以暂时从驻留集中调出到外存,而在工作集中的页面需要调入到驻留集中,也就是从外存中调入内存。

请说一下页面置换采用的相关策略?
分配的时候有两种:固定分配和可变分配
置换的时候也有两种:全局置换和局部置换
因此,可以结合起来一共有三种策略:
固定分配局部置换:每个进程的驻留集事先就分配好并且不可以改变,如果发生置换,只能从自己进程的物理块进行置换
可变分配全局置换:每个进程的驻留集是可以动态改变的,如果发现缺页的时候,就从空闲物理块中分配一定的物理块给该进程。当发生页面置换的时候,可以将别的进程的物理块换出到外存。
可变分配局部置换:可以根据缺页率动态的增加和减少物理块,更加灵活。页面置换的时候只能操作自己的物理块。
覆盖技术和虚拟存储技术有何本质不同?交换技术与虚拟存储技术的调入/调出技术有何相同和不同之处?
覆盖技术和虚拟存储技术:
不同点:覆盖程序程序段的大小收到内存大小限制,而虚存中的程序大小受到地址总线宽度,也就是寻址范围的限制
覆盖程序段由程序员设计,各个覆盖具有相对独立性。虚拟存储技术对用户程序段没有这种要求。
交换技术和虚拟存储技术:
相同点:都是在内存和外存中交换信息
区别:交换技术交换的是整个进程,而虚拟存储器调入/调出的是页面或者分段,更加灵活。
交换技术不允许进程的大小比内存大,而虚拟存储器的大小依赖于地址总线的宽度。
六.文件系统
文件在外存在如何存放?有哪些常用的文件分配方式?有什么优缺点?(对非空闲块的管理)
背景知识:因为和内存分页的存储一样,磁盘也会被分为一个个”块”。一般来说,为了存储方便,会将磁盘块的大小与内存块,页面大小相同。
文件是存储在外存中的文件区的。对于文件来说也有逻辑地址和块内地址的形式。由操作系统来实现逻辑地址到物理地址的映射。
文件分配方式就是实现如何将文件分配给磁盘块中。常用的文件分配有以下几种。
连续分配:就是要求每个文件在磁盘中占用连续的块。
这样逻辑地址到物理地址的映射只需要通过一个文件目录表,文件目录表记录的每个文件名的起始块号和长度。
优点在于实现简单,存取速度快。
缺点在于有可能会产生外部碎片,如果需要解决外部碎片,可能需要紧凑技术,浪费系统资源。而且如果文件长度增加,不容易扩展。
链接分配:链接分配有两种。一种是隐示链接,还有一种是显示链接。
所谓隐示链接就是给文件分配的磁盘块可以通过链表的形式离散的放入磁盘当中。
而文件目录表的目录项(FCB),只需要记录当前文件在磁盘的起始块号和结束块号即可。
优点在于方便文件的扩充,不会产生外部碎片。
缺点就是不支持随机访问,而且增加了I/O次数,并且指针本身也占有了磁盘块的资源。
另外一种就是显示链接,显示链接需要一个FAT文件分配表,FAT其实就是一个静态链表的数据结构。FAT记录了磁盘的所有物理块号和下一块的位置。
FCB只需要记录每个文件的起始块号即可。
显示链接的好处是即支持随机访问也支持顺序访问。而且FAT是在内存当中的,因此访问文件时逻辑块号到物理快号的的转变不需要再访问磁盘,访问速度提高。
但是缺点就在于FAT本身也需要占用一定的内存空间。
另外所有的链接分配都不会产生外部碎片。
索引分配:所谓索引分配就是为每一个文件分配一个索引表,索引表是放在磁盘当中形成一个索引块。
因为索引表记录着每一个文件的逻辑块号到物理块号的映射,所以通过索引表就可以实现逻辑地址到物理地址的转换。
文件目录表的目录项记录了每个索引块的位置。
优点在于:索引分配支持随机访问(直接查找索引表中的逻辑块,逻辑块在索引表中是顺序存储的),并且方便进行文件扩展(随便找到磁盘中空闲块,把映射关系记录到索引表中即可)。
缺点在于:索引本身也占用一定的外存空间。
总结,直接存取索引(可以实现随机访问的索引)有连续分配和索引分配。
如果一个索引表太大,一个磁盘块(索引块)无法存储怎么办?
第一种方法为链接方案,把分配多个索引块,每个索引块分配一个指针,指向下一个索引块,形成一个链表的形式。但是这种这种方式,如果采用文件较大的话,索引块也会非常多。
为了改进这个问题,引入了多级索引。如果采用二级索引,即使用一级索引块指向二级索引块,二级索引块再指向目标数据块。这样对于大型文件来说,提高了搜索速度。
但多级索引还有一个问题,就是每增加一层索引,就需要多一次磁盘I/O操作。
尤其对于一个小文件来说,也需要多次的磁盘I/O操作才能访问相应的数据块。
因次为了解决大小文件不同的情况,采用了混合索引方式。即对于小文件采用的是直接寻址。而中等文件采用单级索引。大型文件可采用二级或者三级索引。
顶级索引块是否调入内存,会影响磁盘I/O的次数。

软连接和硬链接?
对于软连接来说,建立一个软连接时直接复制原文件的计数值,删除文件时对于软连接是不可见的,即索引结点2的Count值不会改变。另外,由于软连接会根据存放路径找到文件的存放位置,因此需要访问多层目录,也就意味着多次I/O操作,速度比硬链接要慢。

对于硬链接来说,需要将计数值加一,删除的时候相应的计数值要减一。当计数值为0的时候,意味着真正的删除此文件。

请介绍一个常用的空闲块的管理方法?
空闲表法

空闲链表法:空闲盘块链和空闲盘区链
空闲盘块链

分配的含义是减少空闲盘块的个数(从前往后删除),回收的意思是增加空闲盘区的个数(尾插法)

位示图法:

成组链接法:

为什么要引入文件系统?
从操作系统的角度来看:文件系统对文件的存储空间进行组织,分配,负责文件的存储,保护和检索。
从用户的角度来看,文件系统主要是实现对文件的按名存储。

打开一个文件的过程是什么?
将文件的FCB(FCB=文件目录项)存入内存的活跃文件目录表,而不是将文件内容复制到主存,找到指定文件目录就是打开文件之前的操作。

删除一个文件的过程是什么?
只是删除该文件相关联的目录项和FCB,并不删除文件所在目录

UNIX/Linux系统中,外部设备视为?
记住一句话,unix/Linux系统一切皆文件。包括I/O设备。

文件分配表(FAT)是什么?

文件保护有哪些方法?
口令:访问时提供口令。
(访问控制)用户权限表:通过访问控制表记录各个用户或者各组用户对文件的访问权限
加密保护:密码加密文件
首先密码加密的安全性更高,加密保护机制的灵活性更好。
对于密码加密一般是由用户程序来实现的,更容易扩展。
而访问控制是由操作系统来实现的,这样才能保证其安全性。

七.磁盘管理
为什么要引入磁盘调度算法,有哪些磁盘调度算法?
因为一次磁盘的读/写操作是寻道时间和延迟时间。
其中寻到时间是指 启动磁头臂的时间+移动磁头的时间(找磁道的时间)
延迟时间是指旋转磁盘,使得找到目标找到目标扇区的时间。
其中延迟时间是由磁盘转速r来确定的,通过软件无法提高转速。
所以如果要提高磁盘的读/写时间只能通过减少寻道时间来完成,因此才引入了不同的磁盘调度算法,关于磁盘的调度算法有以下几种。
第一种是先来先服务算法,即访问请求到达的顺序来进行磁盘调度。
第二种是最短寻道时间算法,也就是一种贪心算法,最次优先响应距离磁头最近的磁道访问。
该算法可能会产生饥饿(原因在于如果一个距离磁头更近的磁道一直请求,其他的磁道访问就会产生饥饿)
第三种是扫描算法:每次必须移动到最边缘的磁道,才能改变磁头的移动方向。
缺点是对每个磁道的相应不平均。据此边缘磁道越近的磁道访问频率越高
第四种是循环扫描算法:在扫描算法的基础上,规定了到达边缘磁道的时候立即让磁道返回起点,防止饥饿。
第五种是LOOK算法,是对SCAN算法的改进,规定了只要在磁头移动方向上没有请求,就可以改变磁头方向。
而C-LOOK算法是对C-SCAN算法的改进。只要在磁头移动方向上没有请求,就立即让磁头返回到磁道的起始位置。

对于寻道时间可以通过磁盘调度算法来实现,而延迟时间(移动扇区的时间)怎么提高呐?
对于延迟时间只能通过改变磁盘本身来实现。
首先因为磁头每次从扇区读入一小段时间后,需要一段时间来处理,如果几个存有内容的扇区是连续存放在相邻扇区的话,会出现多旋转一圈的情况。
对于这个问题可以使用交替编号的方法,即逻辑上相邻的扇区在物理上是有一定的间隔。这样读取连续扇区的延迟时间更少。
第二种方法是错位命名,就是让相邻盘面的扇区编号”错位”。还是因为每次读取一个数据的时候,磁头会有一个处理时间。
为什么磁盘的物理地址是(柱面号,盘面号,扇区号)而不是(盘面号,柱面号,扇区号)?
之所以这样是因为如果按照(盘面号 柱面号 扇区号)的形式,是由于在读取物理地址相邻的区域的时候,由于他们所在的磁道大部分是相同的,只是盘号不同。
因此如果先读盘号的话,在改变柱面号的时候需要移动磁头臂,而寻道需要移动磁头臂消耗一定时间。
而采用(柱面号 盘面号 扇区号)的话只是盘面号不同,而柱面号都是相同的,因此只需要激活相应磁盘的磁头臂,而不需要移动磁头。
第二种方法是错位命名,就是让相邻盘面的扇区编号”错位”。还是因为每次读取一个数据的时候,磁头会有一个处理时间。

在磁盘上进行一次读写操作需要哪几部分时间,其中哪部分时间最长?
在磁盘上进行一次读写操作花费的时间由寻道时间,延迟时间和传输时间决定。
其中寻道时间是将磁头移动到指定的磁道所需的时间(移动磁头臂)
第二个是延迟时间,延迟时间是磁头定位到某一磁道的扇区所需时间
第三个是传输时间,从磁盘读出或向磁盘写入数据所经历的时间。
寻道时间是最长的,因为要移动磁头臂。

存储文件的时候,当一个磁道存储不下的时候,剩下部分是存在同一个盘面的不同磁道号,还是存在同一个柱面的不同盘面好?
因为如果存在同一个盘面的不同磁道,必定会移动磁头臂,这会大大增加文件的访问时间。
而存在同一个柱面的不同盘面就不需要移动磁道,所以更好。

旋转延迟的时间与什么有关?
因为磁盘调度算法只能影响寻道时间,而旋转延迟的时间取决于磁盘空闲空间的分配程序和文件的物理结构有关。
连续分配的磁盘中,文件的物理地址联系。而链接分配的磁盘中,文件的物理地址不连续,因此和旋转延迟有关。

磁盘格式化问题?
将一个空白磁盘分成各个扇区以便磁盘控制器能够读和写,称为低级格式化(物理格式化)。
低级格式化为磁盘的每个扇区采用特别的数据结构,一个扇区被分为了头,数据区域和尾部。管理扇区的各种数据结构放在头和尾部,包括扇区校验码(奇偶校验码和CRC循环冗余码)。
校验码用来校验扇区的数据是否发生了错误。
为了能使操作系统将自己的数据结构记录在磁盘上,分为两步。
第一步将磁盘分为多个柱面组成的分区,每个分区可以作为一个独立的磁盘。(C盘,D盘…)
第二步时逻辑格式化(文件系统),操作系统将初始的文件系统的数据结构存储在磁盘上。
这个数据结构包括空闲和已经分配的空间以及一个初始为空的目录。

开机时候的初始化操作,初始化程序存放在哪里?
ROM中存放自举装入程序。完整的初始化程序(自举程序),可以放在磁盘的启动块当中。

坏块如何进行管理?
逻辑格式化的时候在FAT表上表明哪些是坏块。
1.磁盘控制器设置一个坏块链表,把所有的坏块连起来。
2.保留”备用扇区”,替换坏块。坏块对系统透明。

什么是磁臂黏着?
在SSTF、SCAN及CSCAN几种调度算法中,都有可能出现磁臂停留在某个位置不动的情况。例如,有一个或几个进程对某一磁道有着较高的访问频率,即他们反复地请求对一个磁道进行了I/O请求,从而垄断了整个磁盘设备,这一现象称为磁臂粘着。

八.I/O控制
有哪些I/O控制方式?
所谓I/O控制方式,就是从I/O设备中读/写数据的方式。
第一种是程序直接控制方式,这种方式是在没有中断产生的计算机系统当中。
CPU首先会向I/O控制器发送一个读命名,于是I/O设备收到后启动,并且把状态标志位设置为1(表示还未准备好数据)。此时I/O设备就会不断轮询检查控制器的状态(这也是没有中断的原因所在,造成CPU忙等)。之后输入设备把设备送到I/O控制器后,把数据发给数据寄存器,修改状态寄存器为0,表示数据已经准备号。之后CPU轮询检查到设备就绪,开始从数据寄存器读取数据,最后CPU再把CPU寄存器的内容传送内存。
第二种是中断驱动方式。当CPU向I/O控制器发出读命令之后,就可以去执行别的进程,不用再轮询检查状态控制位。当I/O设备读取到数据之后,会向CPU发出一个中断信号,之后CPU会保存当前的运行环境,然后去执行中断处理程序处理该中断。
中断每次只能从I/O控制器读取一个字,而读取大量的字会产生大量的中断,中断处理需要保存当前进程的运行环境,这样就会降低系统的性能
第三种DMA方式,DMA方式的初衷就是减少CPU对于I/O操作的介入频率。所以DMA控制器应运而生。CPU发出读写指令到DMA控制器的I/O控制逻辑上,之后启动DMA进行数据传送,当DMA控制器从磁盘中读入一个字节的时候放入DMA控制器的数据寄存器DR当中,之后再把该字传送到MAR所指示的内存单元中。直到DC到0为止。最后又DMA控制器向CPU发出中断请求。
(也就是说DC中存放的字节数可以形成一个块的大小,当达到一个块的时候再发出中断,这样就不用了这么多次中断了)
DMA控制器将由字为单位的干预减少到由块为单位的干预。这也是和中断驱动方式的优点所在。
但是如果读取多个块的时候,CPU还是需要发出多条I/O指令才可以。
为了一次能读写多个数据块,所以引入了另外一种方式。
I/O通道控制方式。I/O通道可以看做一个小型的CPU。当CPU向I/O通道发出一组读写指令和通道程序首址以及要访问的I/O设备,通道就可以执行通道程序完成相关任务。
由于通道可以处理的数据不再是一个字节或者一块,可以处理一组数据块,这又减少了CPU对与I/O控制的干预。

I/O通道和CPU的区别?
指令单一,没有内存,和CPU共享内存。

DMA方式与I/O通道都是在I/O设备和主存之间建立了一条直接数据通路。
系统将数据从磁盘读到内存的过程?
1.主机向内存写入DMA命令块,DMA控制器写入该命令块的地址
2.CPU继续其他工作,DMA控制器继续直接操纵内存总线,将地址放到总线上传输。
3.启动磁盘,并且从磁盘传输一块数据到内存缓冲区
4.整个传输完成后,DMA控制器发出中断请求
5.执行DMA结束中断服务程序
DMA控制和中断控制方式的区别?
1.中断控制方式中每个数据处理完成后都需要中断CPU,则DMA控制方式则是处理一批数据后才想CPU发出中断。DMA方式传输批量数组,中断传输以字节为单位
2.中断控制方式的数据传送在中断处理时由CPU完成,而DMA控制方式则在DMA控制器的控制下完成。但是数据传输的方向,存放数据的内存始址和传送数据的长度等仍然由CPU控制
3.DMA以存储器为核心,中断控制以CPU为核心。因此DMA方式下能与CPU并行工作。

I/O通道与DMA方式的区别在于什么?
1.DMA方式需要CPU来控制传输的数据块大小,传输的内存位置。
如果引入I/O通道后,只需要I/O通道来控制这些信息。CPU只需要发出启动命令。指出通道相应的操作和I/O设备,该指令就可以启动通道并使通道从内存中调用相应的通道程序。
2.DMA控制器对应一台设备与内存传递数据,而I/O通道可以控制多台设备与内存的数据交换。
3.通道可以使用一些指令灵活改变通道程序,这是DMA控制方式无法做到的。

I/O控制器的组成?

用户程序发出磁盘I/O请求后,系统的正确处理流程为?

其中计算磁盘号,磁头号和扇区号都是在设备驱动程序完成的。

设备分配从安全性考虑有几种方式?
安全分配方式和不安全分配方式。
安全分配方式:为进程分配了一个设备后,就将该进程阻塞,直接本次I/O操作才能将其唤醒。
也就是说一个进程只能申请一个资源,这样就破坏了死锁的”请求和保持”,所以就不会发生死锁。
缺点在于CPU和I/O设备串行。
不安全分配方式:为进程分配了一个设备后,进程可以继续其他I/O请求,只有某个进程得不到满足的时候才能将其阻塞。因此可能发生死锁,但是CPU和I/O可以并行。
静态分配和动态分配?
静态分配:进程运行前就为其分配全部资源,破坏请求和等待条件,不会发生死锁。
动态分配:进程运行过程中动态的分配资源。

什么是SPOOLing技术(假脱机技术)?假脱机技术由哪些部分组成?举一个假脱机技术的实例?
首先说一下什么叫脱机技术,在批处理阶段为了缓和纸带机和CPU之间的速度差异,在一个外围控制机的控制下把纸带机的数据先被输入到更快磁带当中,从而由磁带向CPU传送数据。所谓的脱机是指数据先在外围机下的到处理,不用通过处理机。
那假脱机技术就是利用程序来模拟脱机时外围机输入的功能,输入到磁盘的存储区域称为输入井。而用另一道程序来模拟脱机的时候外围机输出的功能,准备输出到低速设备的区域称为输出井。其中外围机的输入和输出操作做和CPU对数据处理是同时进行的,所以称为假脱机技术。
SPooLing技术由三部分构成:
输入井和输出井
而输入缓冲区和输出缓冲区用来暂存输入到磁盘和从磁盘输出的数据。
输入进程和输出进程就是模拟输入时的外围机和输出时的外围机。
假脱机的应用在于将独占设备改造为共享设备。
比如共享打印机就是一个例子,当用户使用打印机的打印时,并没有直接给该用户分配打印的进程,而是先将数据放到磁盘中的输出井当中。然后为用户申请和填写一个申请打印表放到打印队列上。当打印机空闲的时候,输出进程就会从打印队列中取出首表,然后将打印机中的数据输出到内存缓冲区,再进行打印。

为什么要引入缓冲区?
1.缓解CPU与I/O设备之间速度不匹配问题,CPU把要输出的数据放到内存区就可以处理其他进程了。CPU往缓冲区冲数据的速度是很快的。
2.减少CPU的中断频率。因为对于字符型I/O设备每输出完一个字就需要向CPU发出一次中断,但引入了缓冲区之后,只需要把缓冲区冲满,再发送中断即可。
3.解决数据粒度不匹配问题。输出进程一次可以生成一个块数据,但I/O设备只能输出一个字节。
4.提高CPU与I/O设备之间的并行性。

  • 1
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值