操作系统期末复习

期末复习 小总结一下 看到有人把这门课学/搞成一门背书的课 是真的sb

OS 基本类型及主要特点

批处理操作系统

主要特征

  1. 用户脱机使用计算机。
  2. 自动成批处理。(后备作业)
  3. 单/多道程序运行。

优点:资源利用率高,系统吞吐量大。

缺点:作业周转时间长,交互能力差

分时系统

分时系统采用时间片轮转方式,多个用户服务。

特点

  1. 交互性:用户可以动态提交与控制程 序运行,交互性好。
  2. 多路性:多个用户同时共享一个计算机,充分发挥系统的效率。
  3. 独立性:多个用户相互独立,如同自 己独占计算机一样。

实时系统

实时系统用于实时控制和实时信息处理领域中。

主要特点

  1. 即时响应:保证在控制对象要求的严 格时间内做出响应。(非用户)
  2. 高可靠性:系统本身要安全可靠。 实时系统往往具有一定的专用性,因此系 统资源利用率可能较低。

现代操作系统的主要特征

操作系统的四个基本特征:并发,共享,异步,虚拟

并发

是指两个或多个事件在同一时间间隔内发生。操作系统的并发性是指计算机系统中同时存在多个运行着的程序,因此它应该具有处理和调度多个程序同时执行的能力。在这种多道程序环境下,一段时间内,宏观上有多个程序在同时运行,而每一时刻,单处理器环境下实际仅能有一道程序执行,故微观上这些程序还是在分时地交替执行。操作系统的并发性是通过分时得以实现的。采用并发技术的系统又称为多任务系统 (multitasking system)

PS: 并发和并行的区别(并行是指计算机系统具有可以同时进行运算或操作的特性在同一时间完成两种或两种以上的工作。并行性需要有相关硬件的支持,如多流水线或多处理器硬件环境)。

共享

是指系统中的资源(硬件资源和信息资源)可以被多个并发执行的程序共同使用,而不是被其中一个独占。资源共享有两种方式:互斥访问同时访问

共享性和并发性是现代操作系统两个最基本的特性,互为依存

异步

在多道程序环境下,允许多个程序并发执行,但由于资源有限,进程的执行不是一贯到底。而是走走停停,以不可预知的速度向前推进,这就是进程的异步性。

并发性和异步性可能导致程序产生与时间有关的错误。 (举个例子??)

归根到底是并发进程访问共享变量的事,当多个进程访问共享变量的过程中,就有可能会产生与时间有关的错误,或者是死锁 – 与数据库中需要锁一个道理

操作系统允许出现这样的错误??

解决方法:PV操作

虚拟

虚拟性是一种管理技术,把物理上的一个实体变成逻辑上的多个对应物,或把物理上的多个实体变成逻辑上的一个对应物的技术。采用虚拟技术的目的是为用户提供易于使用、方便高效的操作环境

如:打印机、文件等都采用了虚拟技术。 采用虚拟技术的目的是:友好的接口和提高资源利用率

进程的三种基本状态及转换关系

  1. 运行态running:正在占有处理器运行。
  2. 就绪态ready:具备运行条件,但由于无 CPU暂时不能运行的状态
  3. 等待态wait:阻塞(blocked)态、睡眠 (sleep)态,因等待某种事件的发生而暂时不能运行的状态。

转换:

image-20220624111549062

进程状态转换

  1. 运行态→等待态:等待使用资源或某事件发生, 如等待外设传输。
  2. 等待态→就绪态:相应等待事件己经发生,如 外设传输结束。(等待结束)
  3. 运行态→就绪态:时间片到或出现了更高优先 权进程。(落选)
  4. 就绪态→运行态:进程被调度程序选中。

了解

image-20220624112059223

进程的七状态模型,分为:创造、就绪、执行、堵塞、终止、挂起、就绪、挂起阻塞。

什么是挂起?这样细分状态有啥作用?

用户的请求:可能是在程序运行期间发现了可疑的问题,需要暂停进程。
父进程的请求:考察,协调,或修改子进程。
操作系统的需要:对运行中资源的使用情况进行检查和记账。
负载调节的需要:有一些实时的任务非常重要,需要得到充足的内存空间,这个时候我们需要把非实时的任务进行挂起,优先使得实时任务执行。
定时任务:一个进程可能会周期性的执行某个任务,那么在一次执行完毕后挂起而不是阻塞,这样可以节省内存。
安全:系统有时可能会出现故障或者某些功能受到破坏,这是就需要将系统中正在进行的进程进行挂起,当系统故障消除以后,对进程的状态进行恢复。

作用:考试可以填七个空?

进程死锁的四个必要条件

死锁的定义

一组进程中,每个进程都无限等待被该组 进程中另一进程所占有的资源,因而永远无 法得到资源,这种现象称为进程死锁,这一 组进程就称为死锁进程。

经典IPC问题的两个实例(不要求掌握)

读者–写者问题

哲学家就餐问题

产生死锁的4个必要条件

  1. 互斥条件。并发进程所要求和占有的 资源是不能同时被两个以上进程使用或操作 的,进程对它所需要的资源进行排他性控制。
  2. 非剥夺(非抢占)条件。进程所获得 的资源在未使用完毕之前,不能被其他进程 强行剥夺,而只能由获得该资源的进程自己 释放。
  3. 占有且等待条件。进程每次申请它所需 要的一部分资源,在等待新资源的同时继续 占用已分配到的资源。
  4. 环路条件。存在一种进程循环链,链中 每一个进程已获得的资源同时被下一个进程 所请求。 只要破坏其中一个条件,死锁就可防止。

安全状态的判断、银行家算法的概念

安全状态

系统能按某种顺序, 如<P1, P2, …, Pn> 为每个进 程分配所需资源, 直到最大需求, 使每个进程都可顺 序完成, 称系统处于安全状态。(安全状态一定是没 有死锁发生的)

银行家算法

Dijkstra提出单资源银行家算法,银行家对客户提出下列约束条件:

① 客户必须预先说明所需最大资金量

② 银行给予分配的条件是银行所剩余额大于客户所需余额,否则拒绝

③ 银行满足了客户对资金的最大需求量,客户在资金运作后,应及时归还银行

例子:

image-20220624113555335

称 P2,P1,P3 为安全序列

一句话:把资源先给能满足他所有需求的,然后让他滚蛋,把他的所有的资源拿回来

原语的概念

原语(Primitive) 原语是指在核心态下执行,且不允许被中断的一个过程,是一个原子操作,一个基本执行单位。

为什么我总觉得这个翻译这么sb 语从何处来?这tm和定义有毛线关系

image-20220624114101242

这才算正常翻译好吧 怪不得国内计算机这么lj 发展还不如台湾 连翻译都能翻译成这个shit的样子 还tm好意思出书?真的弱智 我tm一个大大的流汗黄豆

image-20220624114459582

基元(原语)的概念

原语是指在核心态下执行,且不允许被中断的一个过程,是一个原子操作,一个基本执行单位。

即:原语的执行是顺序的,不可并发。 另外,原语是一个过程,可能包括多条指 令代码,与机器指令有差别。

进程调度基本算法[FCFS,RR,优先级]的思想

先来先服务(FCFS,First Come First Serve )

按作业进入后备队列的先后次序,先进入系统的作业优先被选中。 这是一种非剥夺式算法,易实现;但不利于短作业&优待了长作业,可能使短作业周转时间变得很大。影响批作业的平均周转时间。适用于作业调度和进程调度。

在实际操作系统中,尽管很少单独使 用FCFS算法,但和其他一些算法配合 起来,FCFS算法在os中均有实现。 例如: 基于优先级的算法中对于相同 优先级的作业即采用FCFS方式。

轮转法(RR,round robin)

其思想是将CPU计算时间分成若干个时间间隔单位,即时间片。 每个进程每次最多执行1个时间片; 若时间片用完仍未结束,则让出CPU, 排到就绪队列尾部,等待下一次调度。

进程的时间片可以相等,也可以不相等。

image-20220624120920676

该算法仅适用于进程调度,不适用于作业调度。

一句话:给所有人一定时间,干不完就滚到队伍最后去

时间片大小的选取非常重要。

  • 若时间片过短,则调度次数增多, 进程切换次数增加,额外开销增大。

  • 若时间片过长,则降低了并发性, 甚至可能变成先来先服务法。

多级反馈轮转法

其思想是将就绪进程分为多级,较高优先级的队列分配时间片较短。 调度先从高一级就绪队列中选择,同 一队列中按FCFS原则; 若不存在高优先级进程,则从较低一级的就绪队列中选择。

时间片用完而未完成的进程加入低一级就绪队列,但时间片加长。

优先级法

优先级法可用作作业/进程调度策略。 系统或用户按某种原则为作业或进程指定一个优先级,表示其优先权。 该算法的核心是确定进程或作业的优先级。确定优先级的方法可分为静态法和动态法

同步与互斥的概念,以及生产者-消费者模型的并发控制程序设计

临界资源与临界区

临界资源:系统中同时只允许1个进程访问的资源称为临界资源或互斥资源。

临界区:进程中涉及到临界资源的程序段称为临界区(critical region),即不允许多个并发进程交叉执行的一段程序。

进程互斥

临界区的执行原则

有空则进:当无进程执行临界区时,任何进程均可执行自己的临界区;

无空等待:不允许两个以上的进程同时执行临界区;其他进程必须等待;

有限等待:任何执行临界区代码的请求应在有限的时间内得到满足。

P、V操作

Dijkstra 发明了信号量和P、V 操作

使用一个整型变量来累计唤醒次数,称作信号量(semphore)

荷兰语中 尝试(Proberen)和增加或升高 (Verhogen)。

利用信号量和P、V 操作既可以解决并发进程的竞争问题,又可以解决并发进程的协作问题。

P –down(sleep) V – Up(wakeup)

对一个信号量执行P操作,检查其值是否大于0。若该值大于0,则将其值减一(即用掉一个保存的唤醒信号)并继续;若该值为0,则进程将sleep,此时P操作并未结束。检查数值,修改变量值以及可能发生的睡眠操作均为一个单一的、不可分割的原子操作完成。保证一旦一个信号量操作开始,则在该操作完成或阻塞前,其他进程均不允许访问该信号量。这种原子性的操作对于解决同步问题和避免竞争条件是绝对必要的。

1
2
3
4
5
6
7
8
9
P(s)
{
s.value = s.value --;
if (s.value < 0)
{
改当前进程状态为等待状态;
将其PCB插入相应等待队列末尾s.queue;
}
}

V操作对信号量的值增1。如果一个或多个进程在该信号量上睡眠,无法完成一个先前的V操作,则由系统选择一个(如随机挑选)并允许该进程完成他的V操作。

1
2
3
4
5
6
7
8
9
10
V(s)
{
s.value = s.value ++;
if (s.value < = 0)
{
唤醒等待队列s.queue中的1个进程;
改被唤醒进程的状态为就绪态;
并将其插入就绪队列;
}
}

用信号量解决生产者-消费者问题

为了确保信号量能正确工作,最重要的是要采用一种不可分割的方式来实现它。通常是将P,V操作作为系统调用实现。

  1. 用PV 实现进程互斥步骤如下:
  2. 每个互斥资源设1个互斥变量Si信号量变量赋初始值Si=1
  3. 将各进程中的临界区代码段用P(Si)和V(Si)括起来,即可完成进程互斥image-20220624144507975

mutex即为信号量

image-20220624173741835

进程同步概念

指系统中多个进程中发生的事件存在某种时序关系,需要相互合作,共同完成一项任务。 具体说,一个进程运行到某一点时要求另 一伙伴进程为它提供消息,在未获得消息之 前,该进程处于等待状态,获得消息后被唤醒进入就绪态

用PV操作实现进程同步

具体步骤分为三步:

① 为各并发进程设置各自的私用信号量

② 信号量变量赋初值

③ 利用PV原语和信号量规定各进程的执行顺序

image-20220624144803020

用full和empty来保证某种事件的发生顺序或不发生来实现同步 来看一个例题

某银行提供一个服务窗口和10个供顾客等待的座位。顾客到达银行时,若有空座位,则到取号机上领取一个号,等待叫号。取号机每次仅允许一个顾客使用。当营业员空闲时,通过叫号选取一位顾客,并为其服务。顾客及营业员的活动描述如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
cobegin
{
process 顾客
{
从取号机获取一个号码;
等待叫号;
获得服务;
}
process 营业员
{
while(TRUE)
{
叫号;
为顾客服务;
}
}
}coend

请添加必要的信号量和P、V(或wait()、signal())操作,实现上述过程中的互斥与同步。要求写出完整的过程,说明信号量的含义并赋初值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
semaphore mutex=1;   //互斥使用取号机 互斥锁 实现取号的互斥问题
semaphore empty=10; //空座位的数量
semaphore full=0; //已占座位的数量,必须大于0营业员才可以开始服务
semaphore service=0; //等待叫号
cobegin

{
process 顾客i{
P(empty); //申请座位 成功则将空座位减一
P(mutex); //进入临界区 准备取号
从取号机获得一个号;
V(mutex); //离开临界区 取完了号
V(full); //将空座位加1
P(service); // 等待叫号
等待叫号;
}
process 营业员{
while(TRUE)
{
P(full); //营业员面前没人就P
叫号;
V(empty); // 叫完号才能开放一个空位
为顾客服务;
V(service); //叫下一个号
}
}

}
coend

看了网上很多 感觉都不太对 自己写了一个 也不知道对不对。。。应该对一点点

存储管理中重定位的概念及其方式

逻辑地址(虚拟地址)

目标程序中的地址是一个从0开始的地址, 并不是内存的实际地址。 把用户目标程序使用的地址称为逻辑地址 (虚拟地址)。 一个用户作业的目标程序的逻辑地址集合称为该作业的逻辑地址空间。

程序的逻辑地址空间可以是一维的,这时逻辑地址即为从0 开始顺序递增的一个地址序列。 逻辑地址也可以是二维(多维)的,即程序中的地址是不连续的。

物理地址(绝对地址)

我们把主存中的实际存储单元称为物理地址(绝对地址),物理地址的总体相应构成了用户程序实际运行的物理地址空间。 操作系统将内存分为系统区和用户区两个部分。

逻辑地址与物理地址的关系

某个当程序运行时,操作系统则分配一些 地址空间,此时程序和数据的实际地址与原来程序中的逻辑地址并非是一致的。 CPU访问地址的只能是物理地址,因此, 逻辑地址必须转换成正确的物理地址!

一句话

物理地址=逻辑地址+分区起始地址

地址变换

memory map 把程序中逻辑地址转换为物理地址的工作 称为地址转换或地址重定位、地址映射

静态重定位:发生在作业执行前一次完成,多由软件独立完成

动态重定位:发生在程序执行过程中,通常借助于地址转换机构硬件与软件共同实现。

就一个简单的偏移关系 啥都没有

image-20220624155406128

请求页式管理的地址重定位过程(计算)未总结完

虚拟内存

基本思想:

每个程序拥有自己的地址空间,这个空间被分割成很多块,每一块称作一页或页面。每一页拥有自己的地址空间。

分页

大部分虚拟内存系统中都使用一种成为分页(paging)的技术。在使用虚拟内存的情况下,虚拟地址不是直接送到内存总线上,而是被送到内存管理元(MMU),MMU把虚拟地址映射为物理内存地址。

页框

把虚拟地址空间按照固定大小大小划分成被称为页面的若干单元,在物理内存中对应的单元成为页框

页表

虚拟地址到物理地址的映射可以概括如下:虚拟地址被分为虚拟页号(高位部分)和偏移量(低位部分)两部分。

虚拟页号可用作页表的索引,以找到该虚拟页面对应的页表项。有页表项可以找到页框号(如果有的话)。然后把页框号拼接到偏移量的高位端,以替换掉虚拟页号,形成送往内存的物理地址。

页表的目的是把虚拟页面映射成页框。从数学角度说,也表示一个函数,它的参数是虚拟页号,结果是物理页号。

计算

虽然不觉得这种计算有任何的意义

image-20220624162641093

存储页框表:

即物理内存分配情况,包括空闲页框位置、空闲页框总数等,整个系统1张存储页框表。 实现形式有位示图和空闲链表。

位示图:包含若干个字,每个字包含若干位,每位对应1个页框。1分配,0空闲。

image-20220624162912940

这里应该是打错了 应该是页框号

地址变换

物理地址=页框号*页大小+页内地址

image-20220624163532078

PS:这里应该叫虚拟地址空间

内存映射

虚拟(请求)页式管理

引入原因

  • 程序大于内存

  • 程序暂时不执行或运行完是否还要占用内存

基本原理

系统把程序当前使用部分保留在内存,而把其它部分保存在磁盘上,在需要时在内存和磁盘之间动态交换。

不足:以时间换空间!

存储管理中碎片的概念,及不同存储管理方法出现的碎片问题

碎片

这部分做大作业时应该就已经讲过了。。。

不能被有效利用的空闲部分称为碎片。

内部碎片:在已分配区域中,未被有效利用的部分。

外部碎片:它本身是一个空闲区,但由于容量较小,实际上不能被再次分配。

碎片问题解决

紧凑技术:通过在内存移动程序,将所有小的空闲区域合并为大的空闲区域 (也称:紧缩技术,浮动技术,移动技术)

问题:开销大

例题

image-20220624164041655

内存管理主要包括:连续内存管理、分页、分段。

突然发现自己不会。。。

内部碎片就是为每个进程分布的内存空间之中所没有被使用到的内存碎片。通常出现在分页式存储管理之中。分页式是什么应该很好理解,就是把内存按照分为一页页大小相同的页面,然后再把这些页面分配给进程。因此,在分配给进程时可能会出现这样的情况:
进程需要3MB,分给他4页,每页1MB,这样4>3,就会造成1MB的内部碎片。
而分段式存储管理为什么不会产生内部碎片?

归根结底是由分段本身的定义出发的。如果说分页式是系统对内存的分割,那么分段式就是用户对程序数据的分割。
分页式是没有任何逻辑意义的,而分段式是有其意义在的。
比如说一个程序有主程序段Main类,有通用库,有数据段,这样我们就把这个程序分为三段,分别对应Main,库,数据(说的是最浅显的,详细的可以百度其他),是有逻辑意义的独立单位。都这样分了,怎么还会出现内部碎片?反之,如果是分页式,就可能出现Main类横跨两页,且整个程序装入内存后还有碎片空间的可能了。
总之,引入分段式存储管理本就在一定程度上解决了内部碎片,并且满足了用户的需求。但是分段式存储管理也有不足之处,内存利用率变低了。
因此又引入之后的段页式存储管理方式。

见下个章节

段页式存储管理的数据结构及重定位过程(概念)

内存分段

程序是由若干个逻辑分段组成的,如可由代码分段、数据分段、栈段、堆段组成。不同的段是有不同的属性的,所以就用分段(Segmentation)的形式把这些段分离出来。

分段机制下,虚拟地址和物理地址是如何映射的?

内存分段-寻址的方式
  • 段选择子就保存在段寄存器里面。段选择子里面最重要的是段号,用作段表的索引。段表里面保存的是这个段的基地址、段的界限和特权等级等。
  • 虚拟地址中的段内偏移量应该位于 0 和段界限之间,如果段内偏移量是合法的,就将段基地址加上段内偏移量得到物理内存地址。

在上面,知道了虚拟地址是通过段表与物理地址进行映射的,分段机制会把程序的虚拟地址分成 4 个段,每个段在段表中有一个项,在这一项找到段的基地址,再加上偏移量,于是就能找到物理内存中的地址,如下图:

内存分段-虚拟地址与物理地址

如果要访问段 3 中偏移量 500 的虚拟地址,我们可以计算出物理地址为,段 3 基地址 7000 + 偏移量 500 = 7500。

分段的办法很好,解决了程序本身不需要关心具体的物理内存地址的问题,但它也有一些不足之处:

第一个就是内存碎片的问题。
第二个就是内存交换的效率低的问题。

分段为什么会产生内存碎片的问题?

我们来看看这样一个例子。假设有 1G 的物理内存,用户执行了多个程序,其中:

游戏占用了 512MB 内存
浏览器占用了 128MB 内存
音乐占用了 256 MB 内存。
这个时候,如果我们关闭了浏览器,则空闲内存还有 1024 - 512 - 256 = 256MB。

如果这个 256MB 不是连续的,被分成了两段 128 MB 内存,这就会导致没有空间再打开一个 200MB 的程序
内存碎片的问题

这里的内存碎片的问题共有两处地方:

外部内存碎片,也就是产生了多个不连续的小物理内存,导致新的程序无法被装载;
内部内存碎片,程序所有的内存都被装载到了物理内存,但是这个程序有部分的内存可能并

不是很常使用,这也会导致内存的浪费;
针对上面两种内存碎片的问题,解决的方式会有所不同。

解决外部内存碎片的问题就是内存交换。

可以把音乐程序占用的那 256MB 内存写到硬盘上,然后再从硬盘上读回来到内存里。不过再读回的时候,我们不能装载回原来的位置,而是紧紧跟着那已经被占用了的 512MB 内存后面。这样就能空缺出连续的 256MB 空间,于是新的 200MB 程序就可以装载进来。

这个内存交换空间,在 Linux 系统里,也就是我们常看到的 Swap 空间,这块空间是从硬盘划分出来的,用于内存与硬盘的空间交换。

再来看看,分段为什么会导致内存交换效率低的问题?

对于多进程的系统来说,用分段的方式,内存碎片是很容易产生的,产生了内存碎片,那不得不重新 Swap 内存区域,这个过程会产生性能瓶颈。

因为硬盘的访问速度要比内存慢太多了,每一次内存交换,我们都需要把一大段连续的内存数据写到硬盘上。

所以,如果内存交换的时候,交换的是一个占内存空间很大的程序,这样整个机器都会显得卡顿。

为了解决内存分段的内存碎片和内存交换效率低的问题,就出现了内存分页。

段页式内存管理

内存分段和内存分页并不是对立的,它们是可以组合起来在同一个系统中使用的,那么组合起来后,通常称为段页式内存管理

段页式地址空间

段页式内存管理实现的方式:

先将程序划分为多个有逻辑意义的段,也就是前面提到的分段机制;
接着再把每个段划分为多个页,也就是对分段划分出来的连续空间,再划分固定大小的页;
这样,地址结构就由段号、段内页号和页内位移三部分组成。

用于段页式地址变换的数据结构是每一个程序一张段表,每个段又建立一张页表,段表中的地址是页表的起始地址,而页表中的地址则为某页的物理页号,如图所示:
段页式管理中的段表、页表与内存的关系

段页式地址变换中要得到物理地址须经过三次内存访问:

  • 第一次访问段表,得到页表起始地址;
  • 第二次访问页表,得到物理页号;
  • 第三次将物理页号与页内位移组合,得到物理地址。

可用软、硬件相结合的方法实现段页式地址变换,这样虽然增加了硬件成本和系统开销,但提高了内存的利用率。

Linux 内存管理

那么,Linux 操作系统采用了哪种方式来管理内存呢?

在回答这个问题前,我们得先看看 Intel 处理器的发展历史。

早期 Intel 的处理器从 80286 开始使用的是段式内存管理。但是很快发现,光有段式内存管理而没有页式内存管理是不够的,这会使它的 X86 系列会失去市场的竞争力。因此,在不久以后的 80386 中就实现了对页式内存管理。也就是说,80386 除了完成并完善从 80286 开始的段式内存管理的同时还实现了页式内存管理。

但是这个 80386 的页式内存管理设计时,没有绕开段式内存管理,而是建立在段式内存管理的基础上,这就意味着,页式内存管理的作用是在由段式内存管理所映射而成的地址上再加上一层地址映射。

由于此时由段式内存管理映射而成的地址不再是“物理地址”了,Intel 就称之为“线性地址”(也称虚拟地址)。于是,段式内存管理先将逻辑地址映射成线性地址,然后再由页式内存管理将线性地址映射成物理地址。

Intel X86 逻辑地址解析过程

img

这里说明下逻辑地址和线性地址:

程序所使用的地址,通常是没被段式内存管理映射的地址,称为逻辑地址;
通过段式内存管理映射的地址,称为线性地址,也叫虚拟地址;
逻辑地址是「段式内存管理」转换前的地址,线性地址则是「页式内存管理」转换前的地址。

了解完 Intel 处理器的发展历史后,我们再来说说 Linux 采用了什么方式管理内存?

Linux 内存主要采用的是页式内存管理,但同时也不可避免地涉及了段机制。

这主要是上面 Intel 处理器发展历史导致的,因为 Intel X86 CPU 一律对程序中使用的地址先进行段式映射,然后才能进行页式映射。既然 CPU 的硬件结构是这样,Linux 内核也只好服从 Intel 的选择。

但是事实上,Linux 内核所采取的办法是使段式映射的过程实际上不起什么作用。也就是说,“上有政策,下有对策”,若惹不起就躲着走。

Linux 系统中的每个段都是从 0 地址开始的整个 4GB 虚拟空间(32 位环境下),也就是所有的段的起始地址都是一样的。这意味着,Linux 系统中的代码,包括操作系统本身的代码和应用程序代码,所面对的地址空间都是线性地址空间(虚拟地址),这种做法相当于屏蔽了处理器中的逻辑地址概念,段只被用于访问控制和内存保护。

我们再来瞧一瞧,Linux 的虚拟地址空间是如何分布的?

在 Linux 操作系统中,虚拟地址空间的内部又被分为内核空间和用户空间两部分,不同位数的系统,地址空间的范围也不同。比如最常见的 32 位和 64 位系统,如下所示:

用户空间与内存空间

通过这里可以看出:

32 位系统的内核空间占用 1G,位于最高处,剩下的 3G 是用户空间;
64 位系统的内核空间和用户空间都是 128T,分别占据整个内存空间的最高和最低处,剩下的中间部分是未定义的。
再来说说,内核空间与用户空间的区别:

进程在用户态时,只能访问用户空间内存;
只有进入内核态后,才可以访问内核空间的内存;
虽然每个进程都各自有独立的虚拟内存,但是每个虚拟内存中的内核地址,其实关联的都是相同的物理内存。这样,进程切换到内核态后,就可以很方便地访问内核空间内存。

每个进程的内核空间都是一致的

接下来,进一步了解虚拟空间的划分情况,用户空间和内核空间划分的方式是不同的,内核空间的分布情况就不多说了。

我们看看用户空间分布的情况,以 32 位系统为例,我画了一张图来表示它们的关系:

虚拟内存空间划分

通过这张图你可以看到,用户空间内存,从低到高分别是 7 种不同的内存段:

程序文件段,包括二进制可执行代码;
已初始化数据段,包括静态常量;
未初始化数据段,包括未初始化的静态变量;
堆段,包括动态分配的内存,从低地址开始向上增长;
文件映射段,包括动态库、共享内存等,从低地址开始向上增长(跟硬件和内核版本有关);
栈段,包括局部变量和函数调用的上下文等。栈的大小是固定的,一般是 8 MB。当然系统也提供了参数,以便我们自定义大小;
在这 7 个内存段中,堆和文件映射段的内存是动态分配的。比如说,使用 C 标准库的 malloc() 或者 mmap() ,就可以分别在堆和文件映射段动态分配内存。

页框调度的概念,抖动现象及其可能的因素

页框置换算法(页框调度)

置换算法选出一个合适的页(框)淘汰。

(1)最佳页框算法(OPT) 淘汰后不再需要的或最远的将来才会用到 的页。难实现

(2)先进先出算法(FIFO) 选择内存中驻留时间最长的页淘汰,访问 位保存页的装入时间。简单,效率低

(3)最近最久未用算法(LRU) 选择最后一次访问时间距离当前最久的页 淘汰,即淘汰最长时间没有使用的页。 访问位保存最近访问的时间。局部原理

颠簸(抖动):

在虚拟存储系统中,由于过量的页框调度, 系统难以有效工作,系统效率急剧下降,该 现象称为颠簸或抖动(Thrashing)。

原因:

  • 页框淘汰算法不合理

  • 分配给进程的物理页框数太少;

文件逻辑结构、文件物理结构的概念及分类(特点)

逻辑结构(逻辑文件)

文件的逻辑结构和组织是从用户观点出发, 研究用户概念中的信息组织方式。 文件的逻辑结构分两种形式:一种是流式文件,另一种是记录式文件

流式文件指:

文件内的数据不再分单位, 只是一串信息序列集合,即是无结构的 文件。 这种文件常常按长度来读取所需信息, 也可用插入的特殊字符作为分界。

记录式文件:

是一种有结构的文件,它由若干逻辑记录组成。 逻辑记录是文件中按信息在逻辑上的独立含 意划分的一个信息单位,记录在文件中的排列可能有一定顺序关系

???为什么和网上的不一样 有用的不交 净在这整些花里胡哨的

物理结构(物理文件)

文件的物理结构是指文件在存储设备上的存 放方法和形态。 存储空间常被划分为若干个大小相等的物理 块。文件信息也划分为等大的逻辑块。 文件的访问以块作为分配和传送信息的基本单位。

(1) 连续文件

连续文件是把逻辑上连续的文件信息顺序 地存储到连续物理块中。 优点:已知起址和长度即可访问;顺序存取 效率高。 不足:难以动态增长;可能存在较多零头。 因此,该类文件比较适宜存储备份性文件。

(2) 链接文件

链接文件结构用非连续的物理块来存放文件 信息,通过指针链接在一起。 优点:只需指明第1个块号即可访问;易于动 态增长。 缺点:只能顺序访问,效率较低。 因此,链接文件结构不适宜随机存取。

(3) 索引文件

系统为每个文件建立1张索引表,保存文件 的逻辑块号和物理块号的对应关系。类似于页 表。 文件说明信息项给出文件索引表的物理地址。 索引文件结构既可以满足动态增长,也可进 行随机存取。

I/O 控制方式的类型及特点

外围设备和内存之间的常用数据传送控制方式有4种。即:

(1) 程序直接控制方式

由用户进程来直接控制内存或CPU和外围设备之间的信息传送。 当用户进程需要传输数据时,它通过CPU 发出启动设备命令,然后,用户进程进入测试等待状态,直到相应设备空闲,且准备好, 即开始传输数据

优点:控制简单,不需要多少硬件支持;

缺点:

(1)CPU和外围设备串行工作,CPU利用率低;

(2)CPU只能和一台外围设备交换数据信息,从 而不能实现设备之间的并行工作;

(3)由于程序直接控制方式依靠测试设备标志触 发器的状态位来控制数据传送,因此无法发现和处 理由于设备或其他硬件所产生的错误。 因此,该方式只适用于CPU速度慢,外围设备较 少的系统。

**(2) 中断控制方式 **

这种方式要求CPU与设备(或控制器)之间 有相应的中断请求线,且在设备控制器的控 制状态寄存器中保存中断允许位。 基本步骤:

​ (1) 进程通过CPU发出启动外围设备准备 数据指令,同时将中断允许位置1。

​ (2) 在进程发出指令启动设备之后,该进程 放弃处理机,等待输入完成。

​ (3) 当输入完成时,I/O控制器通过中断请 求线向CPU发出中断信号。

​ (4) CPU在接收到中断信号之后,转向中 断处理程序将被中断进程状态设置为就绪。

​ (5) 进程调度选中该进程后,该进程即从约 定的内存单元中取出数据继续工作。

优点:中断方式支持多道程序和设备的并行 操作,提高CPU利用率;

缺点:

1)中断发生在I/O设备数据缓冲器装满数 据时,而数据缓冲器通常较小,因此,一次 数据传送发生中断次数较多,将耗去大量 CPU处理时间。

2)如果很多设备通过中断处理方式进行 并行操作,则OS可能由于中断次数急剧增加 而造成CPU无法响应中断和出现数据丢失现 象。

3)如果外围设备速度较高,可能造成数据缓冲器的数据由于CPU来不及取走而丢失。

(3) DMA方式(Direct Memory Access)

即直接存取方式。基本思想是在外围设备和内存 之间开辟直接的数据交换通路。 在DMA方式中,DMA控制器具有比中断方式和程 序直接控制方式时更强的功能。

DMA方式采用窃取或挪用系统的总线控制权把数 据直接送到内存。

即,DMA控制器可用来代替CPU控制内存和设 备之间进行成批的数据交换。

优点:减少了中断次数,DMA控制器与CPU并行, 避免了设备缓冲器中的数据丢失问题; 缺点:

1)DMA方式对外围设备的管理和某些操作仍 由CPU控制。

2)功能较简单,不能满足复杂的I/O 要求。 因此,大中型计算机系统中除了设置DMA器件, 还设置专门的硬件装置—通道。

(4) 通道方式

1)字节多路通道。连接大量慢速外围设备,如 软盘机、纸带机、卡片机等。以字节为单位交叉 地为多个设备轮流服务。

2)选择通道。它用于连接高速磁带机和磁盘机 等设备。选择通道在一段时间内只能执行一个通 道程序,一台设备传输完成后再选择另一设备。

3)数组多路通道。对于磁盘类似设备,虽然传 输时间短,但移臂定位时间长,则使用选择通道在 移臂时间内,通道只能空等。 数组多路通道则先为一台设备执行一条通道命令, 然后再为另一台设备执行一条通道命令。 对于若干台磁盘机,可以按次序交叉传输一批批 信息,这样就避免了移臂操作过长地占用通道。 该技术实质是:对通道程序采用多道程序设计技 术的硬件实现。