• 精选
  • 会员

分时系统让多任务看起来是同时运行

2019年5月4日  来源:小智雅汇 作者: 提供人:laogan45......

6、毫秒级切换的分时系统让多任务看起来是同时运行

多个程序最近在内存中运行得挺好,阿甘没法闲下来喝茶了,经常是一个还没有运行完很快就切换到另一个。

但是这种方式也有一个巨大的缺陷,比如前两天我(薪水计算程序)和一个文字处理程序同时进入内存,这个文字处理程序需要和人类频繁地进行交互,他需要读取硬盘文件的时候,就必须让出CPU;操作系统老大就要求我去计算薪水,我整整运算了5分钟,这才放弃CPU去写文件,可怜的文字处理程序只能在一旁眼睁睁地看着。对人类来说,在5分钟之内文字处理程序毫无反应,像假死了一样。

怎么办?

操作系统老大说:“要不这样,阿甘,你把你的运行时间分成一个个小的时间片,让那些进程使用,一个进程运行一段时间,把当前时间片使用完以后,必须让出CPU,让别的进程使用!这样一来,每个进程都有机会来运行了。”

阿甘张大了嘴巴:“这……这能成吗?每个程序运行一小会儿,那人类看到的岂不就是群魔乱舞了吗?”

“不,你忘了重要的一点,阿甘,你的速度是超级快的,你的1秒相当于人类的10亿秒,所以在缓慢的人类看来,就好像薪水计算程序和文字处理程序同时运行,他们根本感觉不到你在不停地切换进程!”

阿甘说:“这样啊,我试试吧。”

没想到,分时系统一经推出就大获成功,尤其对于那速度超慢的人类而言,他们开着电脑一边听歌,一边上网,一边聊QQ,很是自在,理所当然在认为这些程序就是同时运行的。岂不知阿甘是让音乐播放器运行几十毫秒,然后打断,让浏览器进程运行几十毫秒,再打断,让QQ进程也运行几十毫秒,如此循环往复。

7、多任务运行的内存管理:地址重定位、分块、分页、分段

7.1

多道程序运行,内存的分配可不是个简单的事情。

得记录下每个程序的起始地址, 可以让阿甘再增加一个寄存器,专门用来保存初始地址。

例如对第一个程序,这个地址是 0 , 对第二个程序,这个地址是10000,

运行第一个程序的时候,把寄存器的值置为0 , 当切换到第二个程序的时候,寄存器的值也应该切换成10000。

只要遇到了地址有关的指令, 都需要把地址加上寄存器的值,这样才得到真正的内存地址,然后去访问。 (这叫地址的动态重定位

内存突然说:”老大, 我想到一个问题,假设有个不怀好意的恶意程序,它去访问别人的空间怎么办? 比如说地址2000 至 3000属于一个程序, 但是这个程序来了一条这样的指令 MOV AX [1500], 我们在运行时会翻译成 MOV AX [3500] , 这个3500有可能是别的程序的空间啊“

“唉,那就只好再加个寄存器了,阿甘, 用这个新寄存器来记录程序在内存中的长度吧, 这样每次访问的时候拿那个地址和这个长度比较一下,我们就知道是不是越界了” 老大无可奈何了。

“好吧!” 阿甘答应了,“ 我可以把这两个寄存器,以及计算内存地址的方法,封装成一个新的模块,就叫MMU (内存管理单元)吧, 不过这个东西听起来好像应该内存来管啊”

内存笑着说: “那是不行的,阿甘, 能够高速访问的寄存器只有你这里才有啊 , 我就是一个比你慢100倍的存储器而已!”。

7.2

多个程序最近在内存中运行的挺好,阿甘没法闲下来喝茶了, 经常是一个还没运行完,很快就切换到另外一个。

那些程序也都是好事之徒,听说了这个新的系统,都拼了命,挤破头的往内存中钻。

内存很小,很快就会挤满, 操作系统老大忙于调度,也是忙的不可开交。

更有甚者,程序开始越长越大,有些图形处理的程序,还有些什么叫Java的程序,动不动就要几百M内存, 就这还嚷嚷着说不够。

操作系统头都大了,把CPU和内存叫来商量。

“世风日下,人心不古啊” 内存一边叹气一遍说 “原来批处理的时候那些程序规规矩矩的,现在是怎么了?”

“这也不能怪那些程序, 现在硬件的确比原来好多了,内存,你原来只有几十K, 现在都好几G了, CPU在摩尔定律的关照下,发展的更快,每隔18个月,你的速度就翻一翻” 操作系统老大说。

“那也赶不上这些程序的发展速度,他们对我要求越来越高, 可是把我累坏了” CPU垂头丧气的。

“我们还是考虑下怎么让有限的内存装下更多的程序吧”

“我有一个提议” 阿甘说 “对每个程序,不要全部装入内存,要分块装载,例如先把最重要的代码指令装载进来,在运行中按需装载别的东西。”

内存嘲笑说: “阿甘, 看来你又想偷懒喝茶了,哈哈, 如果每个程序都这样,I/O操作得多频繁, 我和硬盘累死, 你就整天歇着吧”

阿甘脸红了, 沉默了。

“慢着”老大说“阿甘,你之前不是发现过什么原理嘛, 就是从几千亿条指令中总结出的那个, 叫什么来着?”

“噢,那是局部性原理, 有两个:

(1) 时间局部性:如果程序中的某条指令一旦执行,则不久之后该指令可能再次被执行; 如果某数据被访问,则不久之后该数据可能再次被访问。

(2) 空间局部性:指一旦程序访问了某个存储单元,则不久之后。其附近的存储单元也将被访问。“

“这个局部性原理应该能拯救我们, 阿甘, 我们完全可以把一个程序分成一个个小块,然后按块来装载到内存中,由于局部性原理的存在, 程序会倾向于在这一块或几块上执行, 性能上应该不会有太大的损失。”

“这能行吗? ” 内存和阿甘不约而同的问。

“试一试就知道了,这样我们把这一个个小块叫做页框(page frame), 每个暂定4k大小, 装载程序的时候也按照页框大小来进行。”

实验了几天, 果然不出老大所料, 那些程序在大部分时间真的只运行在几个页框中, 于是这种分块装载的方式就确定下来了。

7.3

“既然一个程序可以用分块的技术逐步调入内存,而不太影响性能, 那就意味着,一个程序可以比实际的内存大的多啊!”

阿甘躺在床上,突然间想到这一层, 心头突突直跳, 这绝对是一个超级想法。

“我们可以给每个程序都提供一个超级大的空间,例如4G,只不过这个空间是虚拟的, 程序中的指令使用的就是这些虚拟的地址,然后我的MMU把它们映射到真实的物理的内存地址上, 那些程序们浑然不觉,哈哈,实在是太棒了”

内存听说了这个想法,惊讶的瞪大了双眼: “阿甘,你疯了吧!”

“阿甘的想法是有道理的” 老大说 “只是我们还要坚持一点, 那就是分块装入程序, 我们把虚拟的地址也得分块,就叫做页(page), 大小和物理内存的 页框一样, 这样好映射。”

“老大,看来你又要麻烦了, 你得维持一个页表, 用来映射虚拟页面和物理页面”

“不仅如此, 我还得记录一个程序那些页已经被装载到了物理内存, 那些没有被装载,如果程序访问了这些没被装载的页面,我还得从内存中找到一块空闲的地方, 如果内存已满, 只好把现有的页框置换一个到硬盘上了, 可是,怎么确定那个物理内存的页框可以置换呢? 唉, 又涉及到很多复杂的算法,需要大费一番周折。 你看看,老大不是这么容易当的。”

内存想起来一个问题: “如果程序运行时,每次都得查页表来获得物理的内存页, 而页表也是在内存里, 而我比你慢100倍, 你受得了吗, 阿甘?”

阿甘笑了: “这个问题其实我也考虑了,所以我打算增强我的内存管理单元, 把那些最常访问的页表项放到缓存里, 这样不就快了吗。 ”

内存想想也是, 还是局部性原理, 太牛了。

7.4

分页系统运行了一段时间以后, 又有程序表示不爽了,这些程序嚷嚷着说:

“你们能不能把程序“分家”啊, 例如代码段,数据段,堆栈段,这多么自然, 并且有利于保护,要是程序试图去写这个只读的代码段, 立刻就可以抛出保护异常!”

还有程序说:“页面太小了,实在不利于共享,我和哥们共享的那个图形库, 高达几十M , 得分成好多页来共享,太麻烦了,你们要是做一个共享段该多好!”

......

这样的聒噪声多了, 大家都不胜其烦, 那就“分家”吧。

当然对每个程序都需要标准化, 一个程序被分成代码段,数据段和堆栈段等, 操作系统老大记录下每个段的开始和结束地址,每个段的保护位。

但是在每个段的内部,仍然按分页的系统来处理,除了页表之外,操作系统老大又被迫维护了一个段表这样的东西 。

一个虚拟的内存地址来了以后,首先根据地址中的段号先找到相应的段描述表, 其中有页表的地址, 然后再从页表中找到物理内存, 过程类似这样:

通俗了解计算机系统运行原理?

所有事情都设置好了, 大家都喘了口气,觉得这样的结构大家应该没什么异议了。

老大心情大好,觉得一切尽在掌握,他笑着对CPU阿甘说:

“阿甘,从今天开始,如果有程序想非法的访问内存,例如一个不属于他的段, 我就立刻给他一个警告:Segmentation Fault !”

阿甘说:“那程序收到Segmentation Fault以后怎么处理?”

老大说: “通常情况下就被我杀死, 然后给他产生一个叫core dump的尸体,让那些码农们拿走分析去吧!”

7.5

“我(薪水计算程序)要想进入内存执行,必须得通过操作系统来装载,但是操作系统他就是个大骗子!”

“第一,他和CPU阿甘狼狈为奸,营造了一个假象,让我们以为每个程序都可以使用3G的巨大空间,但实际上那只是虚拟的!我们使用的内存实际上少得可怜!操作系统用一个数据结构(页表)把我的代码/数据在硬盘的位置记录下来,等到真正运行的时候临时装载。”

“第二,他不是把你这个程序一下子全部装入物理内存,而是把你大卸八块,用他的术语讲,叫做页面(page),然后分页按需装入内存,注意,他不是连续装入的,有时候先装入这一块,有时候先装入那一块,最后你都不知道自己身体的各个部位在内存的什么地方,绝对是痛不欲生。”

通俗了解计算机系统运行原理?

“第三,你以为在运行时独占CPU,别做梦了,操作系统通过分配时间片的方式,让我们这些程序,不,准确的来讲是进程来轮转执行,再加上一点进程调度的算法,时不时地把你踢出CPU。由于各个进程切换得非常快,给人类形成了一个假象,好像各个程序在同时执行一样。 你说他是不是个大骗子?”

计算机系统 / 分时系统 / 多任务 / 内存管理

如涉及版权,请著作权人与本网站联系,删除或支付费用事宜。

0000