【特别注意】
答案来源于@不确定的光子和@甘晴void
是两位同学在备考时自己做的,仅供参考,若有不同的地方欢迎讨论。
【2024.6.11更新】更新官方答案,感谢@计科22魏同学找到答案
【试卷评析】
这张卷子比较正,个人感觉能够代表接下来几年的考试方向。如果仔细研究应该会有所收获。
【试卷与答案】
一、(20分,每小题5分)简答题。
1.彩票调度和步长调度采用随机思想有其优势,但没有广泛使用,分析其原因。
答:(书P70)两种方式都不能很好地适合I/O;其中最难的票数分配问题并没有确定的解决方式。
2.简要分析虚拟内存系统的三个主要目标。
答:(书P88)透明,效率,保护。(具体见书)
- 虚拟内存(VM)系统的一个主要目标是透明(transparency)。操作系统实现虚拟内存的方式,应该让运行的程序看不见。因此,程序不应该感知到内存被虚拟化的事实,相反,程序的行为就好像它拥有自己的私有物理内存。
- 虚拟内存的另一个目标是效率(efficiency)。操作系统应该追求虚拟化尽可能高效(efficient),包括时间上(即不会使程序运行得更慢)和空间上(即不需要太多额外的内存来支持虚拟化)。
- 虚拟内存第三个目标是保护(protection)。操作系统应确保进程受到保护,不会受其他进程影响,操作系统本身也不会受进程影响。
3.简要说明临界区、竞态条件、不确定性、互斥执行这四个概念。
答:(书P206)
临界区:访问共享资源的一段代码
竞态条件:多个执行线程大致同时进入临界区
不确定性:程序由一个或多个竟态条件组成,程序的输出因运行而异,具体取决于哪些线程在何时运行。这导致结果也是不确定的。
互斥执行:保证只有一个线程进入临界区,从而避免出现竟态,产生确定的程序输出。
【标准答案】
4.什么是文件系统的崩溃一致性问题?可举例说明。
答:(书P383)
- 文件系统面临的一个主要挑战在于,如何在出现断电(power loss)或系统崩溃(system crash)的情况下,更新持久数据结构。具体来说,如果在更新磁盘结构的过程中,有人绊到电源线并且机器断电,会发生什么?或者操作系统遇到错误并崩溃?由于断电和崩溃,更新持久性数据结构可能非常棘手,并导致了文件系统实现中一个有趣的新问题,称为崩 溃一致性问题(crash-consistency problem)。
- 想象一下,为了完成特定操作,你必须更新两个磁盘上的结构 A 和 B。由于磁盘一次只为一个请求提供服务,因此其中一个请求将首先到达磁盘(A 或 B)。 如果在一次写入完成后系统崩溃或断电,则磁盘上的结构将处于不一致(inconsistent)的状态。
二、(10分)
fork()和exec()是操作系统中两个重要进程操作API:
1.简述fork()和exec()各自功能和作用;(3分)
答:(第5章)fork()用于创建新的进程;exce()可以让子进程执行与父进程不同的程序。
【标准答案】(1)fork()创建进程、exec()使得创建的进程中执行与父进程不一样程序;
2.假设fork()总是成功,如图1 (a)所示程序最终打印多少个“hello world”?(3分)
答:32
3.在终端输入如图1(b)所示执行指令,其中,wc(word count)为单词计数可执行程序,p3.c为被计数的程序文本,分析执行该指令过程中对fork()和exec() 的调用逻辑关系。(4分)
答:(书P32)shell先调用fork()创建子进程,然后关闭标准输出(standard output),打开文件newfile.txt,然后再调用exec(),这将用p3.c覆盖当前进程,并将输出结果重定向到文件中。
【标准答案】(3)主进程调到用 fork()创建子进程;子进程关闭 standard 输出,调到 exec()执行wc 程序并将结果写入 newfile.txt;
图1
三、(20分)
小明学习完这个学期的操作系统,对文件系统有了更深入的认识,想尝试对自己电脑上的文件系统进行优化。小明用工具分析了整个文件系统,得到一些统计数据,如表1所示。小明还通过分析知道他使用的文件系统使用了12个直接指针用于寻址磁盘上的数据块,每个数据块的大小为4KB,指针的大小为4个字节。回答以下问题:
(1)小明想最大程度的节省存储小文件的元数据开销,请问他该如何做?最多能节省多少空间(用MB表示)?(4分)
(2)根据表中哪一条数据可以推断文件系统使用了二级间接指针?为什么?二级间接指针带来的额外空间开销是多少(假设只有1个二级间接指针。这里的空间开销是指除存储文件实际数据之外的元数据空间,或者说存放指针的空间)?(4分)
(3)小明想把电影《阿凡达2》拷贝到他的电脑上,因为电影是8K高清晰度,所以电影文件很大,大小是1TB,虽然小明电脑上的剩余磁盘空间大于1TB,但是他试了几次都没有成功。随后,他把1TB的文件分割成多个文件,每个文件大小为4GB,这样他就能把1TB的电影拷贝到电脑上。小明还是不甘心,想把1TB的电影完整拷贝到电脑上,根据所学知识,分析可能的原因,并给出相应的解决方法。(6分)
(4)小明之前因为硬盘故障丢失了所有的数据,因此他想购买一个家用RAID来保存数据。他想最大可能的利用存储空间,又要保证单个硬盘失效的情况下数据可以自动恢复,同时,因为平时需要经常读写数据,他应该使用哪种综合性能比较好的RAID模式(仅限于教材上讲到的几种)?简单说明理由。(6分)
表1
大多数文件都很小 | 90%的文件小于20KB |
文件系统中包含了许多文件 | 文件系统中文件的数量刚好是100000 |
少数大文件占用了大部分空间 | 最大的文件是3GB |
答:
(1)不用12个直接指针,改为使用5个直接指针。节省空间7*4B*100000*90%(约等于)=2.4MB
(2)第三条,最大文件为3GB;一个页最多存放1024个指针,一级间接指针最多支持4MB的空间,二级间接指针最多支持4GB的空间,故显然需要一个二级间接指针;二级间接指针带来的额外空间开销为该间接指针第一层索引的1个页和第二层索引的1024个页,总共1025个页,每个页4KB,故总共为(4MB+4KB)的额外开销。
(3)可能原因是该电脑的文件系统最多支持二级间接指针,如第(2)问中所计算,二级间接指针最多支持4GB的文件,而小明尝试以4GB作为一个文件成功了。若该系统支持三级间接指针,则最多应支持4TB的文件,显然不符合题意;解决方法:改变文件系统结构,允许使用三级间接指针。
(4)推荐使用RAID5。RAID5的容量为N-1,最大程度地利用了存储空间,同时综合性能较好,尤其是在随机写的模式下表现突出,在随机读的模式下也比RAID4较好。RAID0显然不能保证单个硬盘失效下数据的自动恢复。RAID1没有最大可能地利用存储空间。RAID4显然在随机写模式下逊于RAID5。
- (1)因为%90 的文件小于 20KB,所以可以通过减少直接指针的个数来节省元数据的开销。如果剩下的%10 的文件的大小都在 48KB 以上(意味着 12 个直接指针无法寻址,需要二级指针),那么可以把 12 个直接指针减少到 5 个,因为 4KB * 5 = 20KB,即可以满足%90 的小文件的要求。最多可以节省的空间是:100000 * 0.9 * (12 - 5) * 4 / 1024 * 1024 = 2.4 MB
- (2)从表中的描述“最大的文件是 3GB”可以看出使用了二级指针,因为二级指针可以寻址的文件大小是:4KB * 1024 * 1024 = 4GB,而 12 个一级指针寻址的文件大小是48KB。二级间接指针额外的空间开销是:(1024+1)*4KB,如果写成(1024+1)*4KB + 4Byte 也算正确,4Byte 表示的是二级指针本身占用的空间。
- (3)拷贝 1TB 文件不成功,而分割成多个 4GB 的小文件却可以,从(2)可知文件系统支持 4GB 以下的文件,但不支持大于 4GB 的文件,所以可以通过增加一个三级指针来解决这个问题,三级指针支持的最大文件是:1024*1024*1024*4KB = 4TB
- (4)最大利用存储空间,所以可以排除 RAID 1,镜像方式一半空间用于存储冗余数据。RAID 4 和 RAID 5 都可以支持单个磁盘失效的情况下自动恢复数据,但 RAID 5 因为采用循环存放校验码,随机写性能要比 RAID 4 好很多,所以采用 RAID 5.
四、(15分)
某10位的计算机系统,该系统的页大小为16字节,请分析并回答以下问题:
(1)如果采用线性页表的分页方式,假设每个PTE的表项占用4字节,那么整个页表占用的内存是多少字节?(3分)
(2)如图2所示,采用三级页表的分页方式,当访问虚拟地址0X2B和0XDB时,可能会出现什么情况?(6分)
(3)条件同(2),如果已知虚拟地址0X36B对应的物理地址是0X16B,修改图中的内容使已知的条件满足,并给出分析过程。回答请按下面这种方式给出:比如,将页表PFN 204的第几项PTE A修改为PTE B。(注:图中PFN是用十进制表示)(6分)
图 2
答:
- (2^6)*4B=256B
- 0x2B的VPN为000010,对应PFN201的第3个位置,该位置有效位为1但无PFN值,触发页错误,该页不在物理空间中,需要从磁盘中换入该虚拟地址对应的物理帧;0xDB的VPN为001101,对应PFN204的第2个位置,该位置有效位为0,触发非法访问,这里需要OS介入并进行处理例程,可能会杀死该进程。
- 0x36B的VPN为110110,定位在PFN206的第3行,这里现在有效位是0,要改成1,并且还要修改PFN值为0x16,也就是22。故答案为:将页表PFN206的第3项“-”改为“22”。并且将有效位valid“0”改为“1”。
【特别注意】
页表项(PTE)的valid(有效)位。我的理解是有效位和存在位是不一样的:
有效位表示该页是否合法,
存在位表示该页是否在内存内。
因此,在该题中,
如果有效位为0,则不需要考虑后面的PTE内容,因为该地址非法,此时os介入处理;
如果有效位为1,但存在位为0(题目中体现在PTE内容为-),表示缺页;
如果有效位为1,存在位为1,(题目中体现在PTE有内容)有,就是正常情况。
题目实际上是省略了存在位。这个和CS有很大区别。姑且应付考试即可。
- (1) 虚拟地址空间页数为 2^10/2^4=2^6=64 页,页表大小:4Byte*64=2^8=256Byte;
- (2) 0X2B->00 0010 1011;从最高位每 2 位对应一级页表,定位一个表项;开始 00 对应第一级第 0 项(PFN 197);接着 00 对应第二级第 0 项(PFN 201);接着 10 对应第三级第 2 项,有效位位 1,但没有物理页,操作系统要分配物理页;0XDB->00 1101 1011;从最高位每 2 位对应一级页表,定位一个表项;开始 00 对应第一级第 0 项(PFN 197);接着 11 对应第二级第 3 项(PFN 204);接着 01 对应第三级第1 项,有效位为 0,访问出错。
- (3) 0X36B-> 11 0110 1011;从最高位每 2 位对应一级页表,定位一个表项;开始 11对应第一级第 3 项(PFN 200);接着 01 对应第二级第 1 项(PFN 206);接着 10 对应第三级第 2 项(PFN 206 中 4 项当中的倒数第 2 项),有效位为 0,并且没有相应的 PFN。又因为已知对应的物理地址是 0X16B,所以要将 PFN 206 中的第 2 项 valid 位改为 1,PTE 中的 PFN 修改为 22,因为对应的物理地址是 0X16B ,它对应的二进制是 01 01101011,前六位对应的 PFN,所以 PFN 是 22。
五、(15分)【该题答案经验证正确】
在一个采用页式虚拟存储管理的系统中,有一用户作业,它依次要访问的字地址序列是:115, 228,120,88,446,102,321,432,260,167,若该作业的第0页已经装入主存,现分配给该作业的主存共300字,页的大小为100字。回答下列问题:
(1)计算依次访问的虚拟页号为多少?分配的物理页框数。(5分)
(2)按FIFO页面替换算法将产生多少次缺页中断,缺页中断率为多少?依次淘汰的页号为多少?(5分)
(3)按LRU页面替换算法将产生多少次次缺页中断,缺页中断率为多少?依次淘汰的页号为多少?(5分)
答:
- 依次访问虚拟页号为1,2,1,0,4,1,3,4,2,1。分配的物理页框数为3。
- 5次缺页中断,缺页中断率50%,依次淘汰页号为0,1,2。
- 6次缺页中断,缺页中断率60%,依次淘汰页号为2,0,1,3。
有疑问的同学请注意有没有注意到题中的红色加粗表示的条件。
详细过程如下:
FIFO
(从左往右为队列,先进先出)
每次访问一个新的页面的时候,如果队列中有这个页面,不用管,否则最左边的出列,所有左移一格,新页面入队。
访问 | 事件 | |||
---|---|---|---|---|
0 | ||||
1 | 0 | 1 | 1不命中 | |
2 | 0 | 1 | 2 | 2不命中 |
1 | 0 | 1 | 2 | |
0 | 0 | 1 | 2 | |
4 | 1 | 2 | 4 | 4不命中,0换出 |
1 | 1 | 2 | 4 | |
3 | 2 | 4 | 3 | 3不命中,1换出 |
4 | 2 | 4 | 3 | |
2 | 2 | 4 | 3 | |
1 | 4 | 3 | 1 | 1不命中,2换出 |
LRU
(从左往右为优先队列,优先级为最近访问,越最近访问的放在越在右边)
每次访问一个新的页面的时候,如果队列中有这个页面,把它放在最右边,否则最左边的出列,所有左移一格,新页面入队。
访问 | 事件 | |||
0 | ||||
1 | 0 | 1 | 1不命中 | |
2 | 0 | 1 | 2 | 2不命中 |
1 | 0 | 2 | 1 | |
0 | 2 | 1 | 0 | |
4 | 1 | 0 | 4 | 4不命中,2换出 |
1 | 0 | 4 | 1 | |
3 | 4 | 1 | 3 | 3不命中,0换出 |
4 | 1 | 3 | 4 | |
2 | 3 | 4 | 2 | 2不命中,1换出 |
1 | 4 | 2 | 1 | 1不命中,3换出 |
【标准答案】
![](https://img-blog.csdnimg.cn/direct/a4c33c510b5d4ebaaa6540537cece97c.png)
六、(20分)
某社区新冠疫苗接种点,有一位疫苗接种医师,一个疫苗接种室,一个等候大厅有N张间隔1米的接种者等候椅子。没有接种者时,接种医师就会在接种室处理其他事务。接种者到达接种点,如果发现接种医师在处理其他事务,他就会呼唤接种医师为其接种疫苗;如果发现接种医师在为别人接种疫苗且有空椅子,他就会坐下来等候;如果所有的椅子都坐满了人,他就会离开。
假设利用POSIX信号量及多线程并发机制来实现上述接种者和接种医师。POSIX信号量类型定义为sem_t,三个关键操作为int sem_init(sem_t *sem, int pshared, unsigned int value),int sem_wait(sem_t *s),int sem_post(sem_t *s)。定义一个变量emptyc代表空椅子数量,定义一个互斥信号量mut对椅子数量的增或者减,定义一个同步信号量MP(接种者发送、医师等待),定义一个同步信号量MD(医师发送、接种者等待)。
代码结构为:
//全局变量定义
……
//接种医师线程
{
……
}
//接种者线程
{
……
}
//main函数
{
……
}
回答下列问题:
(1)给出全局变量的定义及可能的赋初值代码。(4分)
(2)给出main中用POSIX函数初始化信号量的代码。(6分)
(3)给出接种者线程和接种医师线程的关键代码。(10分)
【我的答案】
void* doctor(){
while(1)
{
sem_wait(&MD);
sem_wait(&mut);
emptyc++;
sem_post(&mut);
sem_post(&MD);
}
}
void* patient(){
while(1)
{
sem_wait(&mut);
if (emptyc==0)
{
sem_post(&mut);
pthread_exit(NULL);
}
else
{
emptyc--;
sem_post(&mut);
sem_post(&MP);
sem_post(&MD);
pthread_exit(NULL);
}
}
}
int main()
{
……
sem_init(&mut,0,1);
sem_init(&MD,0,0);
sem_init(&MP,0,0);
……
}
【标准答案】
(1)全局变量的定义:
sem_t MP;
sem_t MD;
sem_t mut;
int emptyc=N; //空椅子数量
(2)赋初值的代码
int main(int argc, char *argv[]){
//…
sem_init(&MP, 0, 0);
sem_init(&MD, 0, 0);
sem_init(&mut, 0, 1);
//…
}
(3)接种师线程:
while(true){
sem_wait( &MP );
sem_wait( &mut );
emptyc++;
sem_post( &MD );
sem_post( &mut );
//给人接种…
}
接种者线程:
while(true){
sem_wait( &mut );
if(emptyc>0)
{
emptyc - -;
sem_post( &MP );
sem_post( &mut );
sem_wait( &MD );
//接受接种…
}
else
{
sem_post( &mut );
//离开…
}
}