操作系统导论

转载自 link

操作系统导论

[图片上传失败...(image-13203a-1630146185361)]


image-20210319134800000.png

第4章 进程

运行的程序就是进程,操作系统有很多关于进程的API,

·创建(create):操作系统必须包含一些创建新进程的方法。在shell中键入命令或双击应用程序图标时,会调用操作系统来创建新进程,运行指定的程序。

·销毁(destroy):由于存在创建进程的接口,因此系统还提供了一个强制销毁进程的接口。当然,很多进程会在运行完成后自行退出。但是,如果它们不退出,用户可能希望终止它们,因此停止失控进程的接口非常有用。

·等待(wait):有时等待进程停止运行是有用的,因此经常提供某种等待接口。

·其他控制(miscellaneous control):除了杀死或等待进程外,有时还可能有其他控制。例如,大多数操作系统提供某种方法来暂停进程(停止运行一段时间),然后恢复(继续运行)。

·状态(statu):通常也有一些接口可以获得有关进程的状态信息,例如运行了多长时间,或者处于什么状态。

把程序和静态数据加载到内存,然后执行他就成了进程,现代操作系统将加载的过程lazily懒惰化了,需要用的时候才加载

进程有三个状态,运行、就绪、阻塞

第5章 进程API

fork , 复制当前的进程,父进程返回子进程pid,子进程返回0

wait,父进程等待子进程执行完毕

exec,加载某个程序到内存中运行,覆盖当前进程

shell也是一个用户程序[插图],它首先显示一个提示符(prompt),然后等待用户输入。你可以向它输入一个命令(一个可执行程序的名称及需要的参数),大多数情况下,shell可以在文件系统中找到这个可执行程序,调用fork()创建新进程,并调用exec()的某个变体来执行这个可执行程序,调用wait()等待该命令完成。子进程执行结束后,shell从wait()返回并再次输出一个提示符,等待用户输入下一条命令。

第6章 机制:受限直接执行

OS不可能说,创建了一个进程,把所有权限完全交给进程,然后把自己挂起,那坏蛋写一个死循环,我们就只能重启计算机了,OS会把CPU交给进程,但是他如何拿回来呢?

答案很简单,许多年前构建计算机系统的许多人都发现了:时钟中断(timer interrupt)[M+63]。时钟设备可以编程为每隔几毫秒产生一次中断。产生中断时,当前正在运行的进程停止,操作系统中预先配置的中断处理程序(interrupt handler)会运行。此时,操作系统重新获得CPU的控制权,因此可以做它想做的事:停止当前进程,并启动另一个进程。

<span style="color:red">第8章 调度:多级反馈队列</span>

·规则1:如果A的优先级 > B的优先级,运行A(不运行B)。

·规则2:如果A的优先级 = B的优先级,轮转运行A和B。

·规则3:工作进入系统时,放在最高优先级(最上层队列)。

·规则4:一旦工作用完了其在某一层中的时间配额(无论中间主动放弃了多少次CPU),就降低其优先级(移入低一级队列)。

·规则5:经过一段时间S,就将系统中所有工作重新加入最高优先级队列。

规则4是反馈

规则5可避免饥饿

第9章 调度: 比例份额

彩票调度

很多人都买过彩票,但是很少有人中奖,我们假设有100张彩票,有AB两个人分别买了75张和25张,然后我们进行随机开奖,开到一张票,这张票在谁手上谁就中奖。

同理,我们假设AB是两个进程,则中奖的那位就能获得CPU控制权。

彩票货币

如果进程可以将自己的彩票分配给自己的线程,则实现了彩票货币化。

彩票转让

一个进程可以吧自己的彩票分给其他进程,例如客户端把彩票分给服务端以加快服务端处理速度。

彩票通胀

最后,彩票通胀(ticket inflation)有时也很有用。利用通胀,一个进程可以临时提升或降低自己拥有的彩票数量。当然在竞争环境中,进程之间互相不信任,这种机制就没什么意义。

算法实现

我们只需要记录每个进程拥有多少彩票,并把他们排好,然后OS生产随机数,从第一个进程开始,对彩票数进行累加,当累和第一次超过随机数时,这个进程中奖。

我们还可以对进程按照彩票数从大到小排好序,这样可以加快遍历速度。

步长调度

A、B、C这3个工作的票数分别是100、50和250,我们通过用一个大数分别除以他们的票数来获得每个进程的步长。比如用10000除以这些票数值,得到了3个进程的步长分别为100、200和40。我们称这个值为每个进程的步长(stride)。每次进程运行后,我们会让它的计数器 [称为行程(pass)值] 增加它的步长,记录它的总体进展。

当进行调度的时候,取出行程最小的进程进行调度,如果有多个,则从中随机选择任意一个。

第10章 多处理器调度(高级)

问题

  • 缓存一致性: CPU1修改了自己的缓存,但是CPU2没有同步修改怎么办?

硬件提供了这个问题的基本解决方案:通过监控内存访问,硬件可以保证获得正确的数据,并保证共享内存的唯一性。在基于总线的系统中,一种方式是使用总线窥探(bus snooping)[G83]。每个缓存都通过监听链接所有缓存和内存的总线,来发现内存访问。如果CPU发现对它放在缓存中的数据的更新,会作废(invalidate)本地副本(从缓存中移除),或更新(update)它(修改为新值)。回写缓存,如上面提到的,让事情更复杂(由于对内存的写入稍后才会看到),你可以想想基本方案如何工作

  • 并行(发)问题:

如果线程1执行第一行,会将head的当前值存入它的tmp变量。如果线程2接着也执行第一行,它也会将同样的head值存入它自己的私有tmp变量(tmp在栈上分配,因此每个线程都有自己的私有存储)。因此,两个线程会尝试删除同一个链表头,而不是每个线程移除一个元素,

void rease(){
  Node *tmp = head;
  // ...
  free(tmp);
}
  • 缓存亲和度: 一个线程在某个CPU上运行,他会有一些缓存,如果他切换到其他CPU上,则缓存需要重新加载。

单队列多处理器调度

(Single QueueMultiprocessor Scheduling,SQMS) 一个队列,处理器需要执行时,锁住队列,然后从队列取出任务,最后释放锁,但是他不好解决亲和度问题和锁的问题。

多队列多处理器调度

(Multi-QueueMultiprocessor Scheduling,MQMS)多个队列,一般而言,一个处理器一个队列,如果任务数量能整除CPU数量,这很好分配,无法整除的时候,就涉及到了负载不均的问题。

最明显的答案是让工作移动,这种技术我们称为迁移(migration)。通过工作的跨CPU迁移,可以真正实现负载均衡。

注意我们要让任务轮流迁移,否则就不太公平

另一个方法是窃取工作量少的队列不定期偷看其他队列,如果发现他比自己多,则偷取一个任务。

如果太频繁地检查其他队列,就会带来较高的开销,可扩展性不好,而这是多队列调度最初的全部目标!相反,如果检查间隔太长,又可能会带来严重的负载不均。

第15章 机制:地址转换

动态(基于硬件)重定位

即基址加界限机制,所有的程序都认为自己的地址空间从0开始,但是当他执行的时候,操作系统会决定其在物理内存中的实际加载地址,并将起始地址记录在基址寄存器中。

第16章 分段

问题:栈和堆之间,有一大块“空闲”空间,造成了浪费

在硬件中使用三对寄存器来分别记录代码段,堆和栈

问题: 如何判断一个地址是代码段,堆还是栈?

虚拟地址前两位表示

问题: 如何共享?

操作系统为段记录额外信息,

[图片上传失败...(image-e2b0a1-1630146185361)]

第17章 空闲空间管理

要满足变长的分配请求,应该如何管理空闲空间?什么策略可以让碎片最小化?不同方法的时间和空间开销如何?

OS如何知道free的内存有多大?

在C中,每当我们使用malloc的时候,OS会给我们分配一块内存,当我们使用free的时候,这块内存会被释放,然而这个时候OS如何知道这块内存有多大,他该如何来释放呢?

[图片上传失败...(image-e694b8-1630146185361)]

其实malloc返回给我们的内存是小于OS给我们的内存的,可以看到OS在这块内存的前面加了一些信息,包括内存的大小和一个校验部分。

OS如何组织空闲内存?

每块内存的开头都有一个部分,包括这块内存的大小以及下一块内存的地址

[图片上传失败...(image-fa9087-1630146185361)]

内存分配和释放

OS分配内存的时候,会在他的内存链表中找到一块合适的,将其切割并移除链表分配给应用程序,当OS回收的时候,会将其放回链表,但是这个办法经历了长时间的内存管理以后,OS的内存将会一团糟,这个时候操作系统又会合并相邻块,之后内存又成为了一个整体。

如何选择链表中的内存块?

匹配算法 备注
最优匹配 在所有可以分割的节点中,选择内存最小的那个节点
最差匹配 在所有可以分割的节点中,选择内存最大的那个节点
首次匹配 寻找过程中,发现的第一个能匹配的节点
下次匹配 在首次匹配的基础上,每次查询的链表起点就是上一次匹配的节点

有趣的匹配算法

分离空闲列表:

如果某个应用程序经常申请一种(或几种)大小的内存空间,那就用一个独立的列表,只管理这样大小的对象。其他大小的请求都交给更通用的内存分配程序。

伙伴系统:

[图片上传失败...(image-57eee8-1630146185361)]

第18章 分页:介绍

页表是什么,在哪里?

用一张表,储存虚拟地址到物理地址的映射,往往虚拟地址和物理地址的前几位是不同的,这些不同的位被称为页,而剩下的成为偏移量。从虚拟地址映射到物理地址只需要将前几位进行转换即可,这张表就叫做页表。

页表储存在内存中,每个进程都拥有一份自己的页表。

页表中有什么

页表往往是一个数组映射,所以没有物理叶帧(数组下标)

代号 意义 备注
P 存在位 表示该页表是否被进程申请使用
R/W 读写权限位 表示该页面权限是可读还是可写
U/S 访问是否需要特权级
PWT
PCD
A 访问位 近期是否访问过该页
D 脏位 该页是否被写
PAT
G
操作系统自定义使用
PFN 叶帧

[图片上传失败...(image-2cf011-1630146185361)]

分页很慢

分页机制导致与内存发生的交互次数翻倍了,程序更慢了。

第19章 分页:快速地址转换(TLB)

高速页表缓冲区:地址转换旁路缓冲存储器(translation-lookasidebuffer)

这是一个硬件,他能缓存页表地址转化,速度远高于内存读取

TLB未命中

TLB和其他缓存相似,前提是在一般情况下,转换映射会在缓存中(即命中)。如果是这样,只增加了很少的开销,因为TLB处理器核心附近,设计的访问速度很快。如果TLB未命中,就会带来很大的分页开销。必须访问页表来查找转换映射,导致一次额外的内存引用(或者更多,如果页表更复杂)。如果这经常发生,程序的运行就会显著变慢。相对于大多数CPU指令,内存访问开销很大,TLB未命中导致更多内存访问。因此,我们希望尽可能避免TLB未命中。

一般是操作系统来处理未命中,发生未命中,硬件抛异常,进入内核,陷入操作系统,操作系统更新TLB,返回之前的未命中代码进行重试

重点细节:

  • 返回进入陷阱的那条代码重试。
  • OS千万不能在处理TLB时又触发未命中,这将导致无限递归。

进程上下文切换

页表是进程私有的,如果发生了进程上下文切换,则TLB全部变为无效。

上下文切换的时候清空TLB,这是一个可行的解决方案,进程不会再读到错误的地址映射。但是,有一定开销:每次进程运行,当它访问数据和代码页时,都会触发TLB未命中。如果操作系统频繁地切换进程,这种开销会很高。

为了减少这种开销,一些系统增加了硬件支持,实现跨上下文切换的TLB共享。比如有的系统在TLB中添加了一个地址空间标识符(Address Space Identifier,ASID)。可以把ASID看作是进程标识符(Process Identifier,PID),但通常比PID位数少(PID一般32位,ASID一般是8位)。

TLB项中有什么

TLB是并行硬件,他可以并行查找

代号 意义 备注
VPN
R/W 全局位 是否全局共享
PWT 进程空间 属于哪个进程
PFN
C 一致位 决定硬件如何缓存
D 脏位 是否被写入新数据
V 有效位 该映射是否有效(注意区别页表的存在位)

[图片上传失败...(image-fecf73-1630146185361)]

第20章 分页:较小的表

页表太大,因此消耗的内存太多。

假设一个32位地址空间(232字节),4KB(212字节)的页和一个4字节的页表项。一个地址空间中大约有一百万个虚拟页面(232/212)。乘以页表项的大小,你会发现页表大小为4MB。

使用更大的页

这种方法的主要问题在于,大内存页会导致每页内的浪费,这被称为内部碎片(internalfragmentation)问题

结合分段

我们可能有3个页表,地址空间的代码、堆和栈部分各有一个

杂合方案的关键区别在于,每个分段都有界限寄存器,每个界限寄存器保存了段中最大有效页的值。

分段并不像我们需要的那样灵活,因为它假定地址空间有一定的使用模式。例如,如果有一个大而稀疏的堆,仍然可能导致大量的页表浪费。

多级页表

分配更多级的页表,这是使用时间换空间

反向页表

记录物理页映射到虚拟页,而不是虚拟页映射到物理页

第21章 超越物理内存:机制

我们的内存始终是有限的,如何超越这个限制,为应用程序提供无限空间的假象呢?

操作系统如何利用大而慢的设备,透明地提供巨大虚拟地址空间的假象?

操作系统利用大而慢的磁盘和内存中的数据进行交换,借此实现了超越物理内存的目的。

页错误

如果一个页不存在,它已被交换到硬盘,在处理页错误的时候,操作系统需要将该页交换到内存中。那么,问题来了:操作系统如何知道所需的页在哪儿?在许多系统中,页表是存储这些信息最自然的地方。因此,操作系统可以用PTE中的某些位来存储硬盘地址,这些位通常用来存储像页的PFN这样的数据。当操作系统接收到页错误时,它会在PTE中查找地址,并将请求发送到硬盘,将页读取到内存中。

交换何时发生?

OS不会等到内存完全满了才进行交换,OS往往会预留BUF。

为了保证有少量的空闲内存,大多数操作系统会设置高水位线(High Watermark,HW)和低水位线(Low Watermark,LW),来帮助决定何时从内存中清除页。原理是这样:当操作系统发现有少于LW个页可用时,后台负责释放内存的线程会开始运行,直到有HW个可用的物理页。这个后台线程有时称为交换守护进程(swap daemon)或页守护进程(page daemon)[插图],它然后会很开心地进入休眠状态,因为它毕竟为操作系统释放了一些内存

第22章 超越物理内存:策略

最优替换策略

只存在于理论上的策略,他的作用是评估其他算法

FIFO

先进先出

补充:Belady的异常Belady(最优策略发明者)及其同事发现了一个有意思的引用序列[BNS69]。内存引用顺序是:1,2,3,4,1,2,5,1,2,3,4,5。他们正在研究的替换策略是FIFO。有趣的问题:当缓存大小从3变成4时,缓存命中率如何变化?

一般来说,当缓存变大时,缓存命中率是会提高的(变好)。但在这个例子,采用FIFO,命中率反而下降了!你可以自己计算一下缓存命中和未命中次数。这种奇怪的现象被称为Belady的异常(Belady’s Anomaly)。

其他一些策略,比如LRU,不会遇到这个问题。可以猜猜为什么?事实证明,LRU具有所谓的栈特性(stack property)[M+70]。对于具有这个性质的算法,大小为N + 1的缓存自然包括大小为N的缓存的内容。因此,当增加缓存大小时,缓存命中率至少保证不变,有可能提高。先进先出(FIFO)和随机(Random)等显然没有栈特性,因此容易出现异常行为。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 161,780评论 4 369
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,424评论 1 305
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 111,397评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,576评论 0 218
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,997评论 3 295
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,945评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,107评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,850评论 0 208
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,625评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,804评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,285评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,613评论 3 261
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,291评论 3 242
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,164评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,963评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,096评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,886评论 2 278

推荐阅读更多精彩内容

  • 《操作系统导论》第18章习题 参数详细信息 问题1: 答:页表长度或者说页表项等于物理地址空间除以页面大小,页表项...
    Rookie2020阅读 639评论 0 0
  • 引言 出于三个原因,近期有一段时间没怎么写文章了。一、前段时间公司人员变动比较大,工作任务较为繁忙;二、家庭生活中...
    ZhengYaWei阅读 2,511评论 2 11
  • 前言 这个系列是《操作系统导论》的读书笔记。力求简洁、清晰、易懂。 1.OS Operating System,位...
    WinterPrince阅读 1,349评论 0 1
  • 操作系统基本概念 操作系统是计算机科学研究基石之一。 功能 管理硬件(如设备驱动:实现用户提出的I/O操作请求,完...
    Hengtao24阅读 4,299评论 2 14
  • 第一章 操作系统简介第一节 什么是操作系统存储数据是物理地址,外存指硬盘 操作系统是覆盖在逻辑上的第一层软件,为软...
    王2今阅读 1,031评论 0 3