Nachos同步机制实习报告

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

同步机制实习报告善良的大姐姐
2015.3.30
精品文档
目录
一:总体概述 (3)
二:任务完成情况 (3)
任务完成列表(Y/N) (3)
具体Exercise的完成情况 (3)
三:遇到的困难以及解决方法 (12)
四:收获及感想 (12)
内容五:参考文献 (13)
.
精品文档
一:总体概述
Lab3首先要求阅读Nachos系统提供的同步机制代码,即Semaphore的实现。

其次要求修改底层源代码,达到“扩展同步机制,实现同步互斥实例”的目标。

具体来说,即要求在Semaphore 的基础上,实现Lock锁和Mesa管程的Condition(条件变量)。

此外,还要利用编写的同步机制,来实现互斥实例,进而证明同步机制编写的正确性。

二:任务完成情况
任务完成列表(Y/N)
具体Exercise的完成情况
Exercise1:调研
任务:
调研Linux中实现的同步机制
调研情况:
Linux的同步机制包括好几层。

第一层:原子操作。

以x86体系结构为例,定义在linuxX.X/include/asm-i386/atomic.h文件中。

文件内定义了原子类型atomic_t,其仅有一个字段counter,用于保存32位数据。

其中原子操作函数atomic_inc完成自加原子操作。

第二层:自旋锁。

以x86体系结构为例,定义在linuxX.X/include/asm-i386/spinlock.h文件中。

其中__raw_spin_lock 完成自旋锁的加锁功能。

自旋锁达到的效果为,在等待锁的线程会不断地申请锁,直到获得锁或是时间片用尽从而离开CPU。

第三层:信号量
以x86体系结构为例,定义在linuxX.X/include/asm-i386/semaphore.h文件中。

信号量的申请操作使用down函数,释放操作使用up函数。

即通常所说的PV操作。

区别于自旋锁,当一个进程在等待一个锁时,会让出CPU进入休眠状态,直到其他进程释放锁后,将该进程放入可运行队列。

.
精品文档
Exercise2:源代码阅读
任务
阅读下列源代码,理解Nachos现有的同步机制。

code/threads/synch.h和code/threads/
code/threads/synchlist.h和code/threads/
阅读情况
(h)
文件中有三个类:Semaphore, Lock, Condition。

其中Semaphore是已经编写完成的。

主要功能是:通过一个名字和一个初始值可以初始化一个Semaphore。

P函数的作用是:判断当前线程能否进入临界区,如果可以(即初始值≠0),则进入,且初始值减一;如果不能(即初始值=0),则将当前线程放入Semaphore的等待队列中,线程进入休眠状态。

V函数的作用是:如果Semaphore的等待队列不为空,将等待队列的队头线程取出来,将其状态标识为ReadyToRun,并且初始值加1。

另外两个类是本次作业需要完成的,会在之后说明。

(h)
文件中包括一个Synchlist类,实现了一个互斥访问的队列。

具体来说,类中有一个Append函数,用于将元素加入队列;有一个Remove函数,用于将队头元素移出队列。

而互斥访问的实现方式为:用Lock锁将Append函数体和Remove函数体保
护起来。

保证了二者至多只有一个可以被被CPU运行,直到函数体结束。

(即线程切换的中断不会造成线程交替运行)
这两个函数模拟了monitor(管程)的函数体互斥性,因此在之后的作业中会用到。

Exercise3:实现锁和条件变量
任务
可以使用sleep和wakeup两个原语操作(注意屏蔽系统中断),也可以使用Semaphore作为唯一同步原语(不必自己编写开关中断的代码)。

完成情况
1.Lock
简述:
使用Semaphore作为同步原语,定义的时候创建一个初始值为1的Semaphore。

对应的,Acquire 函数就是执行Semaphore的P函数,Release函数就是执行Semaphore的V函数。

验证正确性:
采用基于优先级抢占式调度,一个线程递归生成优先级更高的线程。

如果没有Lock,那么当前线程就会被抢占,那么运行结果会是这样:
.
精品文档
出连输接before fork
再接连输出after fork
出来的线程才fork但若在线程一开始加上了互斥锁,那么只有当当前线程运行结束后,它能获得锁,才能运行,运行结果如下:
一个线程输before 出了after fork和另之后,fork一个线程才能输出
Condition
.
精品文档
:实现同步互斥实例Exercise4任务
中的信号量、锁和条件变量,采用两种方式实现同步和互斥机制应用(其中使基于Nachos写“读者-。

具体可选择“生产者-消费者问题”、用条件变量实现同步互斥机制为必选题目)等。

(也可选择其他经典的同步互斥问题)、“哲学家就餐问题”、“睡眠理发师问题”者问题”
完成情况-消费者”问题基于Nachos信号量实现“生产者1.
(基于时间片轮转调度,时间片长度随机。

为了使得中断有可能在任何地方发生,在所)有临界区中的代码语句后面都调用了interrupt->onetick
修改情况:
精品文档
测试结果截图:
生产者放入队列的元素发生时间片中断,切换线程
两个消费者交替消费元素
消费者”问题Nachos的条件变量实现“生产者-2.基于(基于时间片轮转调度,时间片长度随机。

为了使得中断有可能在任何地方发生,在所)有临界区中的代码语句后面都调用了
.
精品文档
测试结果截图:
两个消费者交替消费,并且不需要和生产者同步。

.
精品文档
测试情况详细分析:
消费者2试图加锁进入管程,但由于管程互斥锁此时在消费者1手中,因此消费者2继续等待
Challenge1:实现barrier
任务
可以使用Nachos 提供的同步互斥机制(如条件变量)来实现barrier,使得当且仅当若干个线程同时到达某一点时方可继续执行。

.
精品文档
次10个Barrier类的函数测试结果截图
用使未Barrier:
Barrier 使用
同步(三个线程均之后才进入输出iinterrupt下一个,表示时间片到了切)换线程。

不同步
read/write lock
:实现Challenge2任务。

使得若干线程可以同时locklock(synch.hNachos提供的和),实现read/write 基于只有一个线程可以向该共享数据区写但是在某一特定的时刻,读取某共享数据区内的数据,入数据。

完成情况(基于时间片轮转调度,时间片长度随机。

为了使得中断有可能在任何地方发生,在
.
精品文档
测试结果截图:。

读以可同时读者之间可finishstart和(以认为是临界区)
写者在临界区里时,即使发生,也无interrupt了(线程切换)法让读者进入。

即读者和写者不能同时访问临界区
.
精品文档
三:遇到的困难以及解决方法
困难1:我在完成lab2线程调度实验中,在readyToRun函数中对当前线程执行了yield操作,导致lab3中V函数的原子性被破坏。

(V函数会调用readyToRun 函数)
解决方式:将线程Yield的过程单独封装成一个函数,readyToRun函数仅仅负责将当前线程放入可执行队列当中。

对于新建的一个线程(可能可以抢占当前线程),先调用该函数,判断是否抢占。

如果抢占,则让当前线程yield;否则,调用readyToRun函数。

困难2:思考如何实现condition的wait函数,曾一度觉得synchlist中会造成死锁
解决方式:详细了解了管程机制之后,发现只要在wait函数中,先对传入的Lock参数执行释放(Release)操作,当前线程再进入休眠状态,问题就可以解决了。

困难3:在写“生产者-消费者”问题的测试函数时,从队列中读出来的值总是等于最后一个加入队列的值(比如加入队列1,2,3,4,读出来会是4,4,4,4)
解决方式:由于传入的是(void *),是一个指针。

因此我直接传入了for循环中的i的地址,这就导致了i的值虽然在变化,但i的地址是不变的,所以读出来总会等于最后一个加入队列的值。

之后专门创建了一个buffer数组,使得不同的值对应不同的地址,问题就解决了。

困难4:一开始是用lock的acquire和release实现condition,但测试函数结果和预期的不相符
解决方式:经过研究,我发现,造成错误的原因,是lock的release函数,会使得value值增加。

这就意味着,即使等待信号的队列为空,signal函数也会释放一个资源。

这样之后,若还有wait 函数调用,就不会被阻塞,而是直接通过。

这不符合管程中wait和signal的语义(我查了上学期操作系统的课件,课件上说,若是等待队列为空,则signal函数为空操作)。

于是我将Lock换成了队列,当队列不为空的时候才让signal和broadcast函数起作用。

四:收获及感想
这次的lab消耗了比预期多的时间,主要问题在于condition的实现。

需要仔细了解了管程机制之后,才知道如何编写。

详情可参看【困难4】。

此外,测试函数也需要开动脑筋,.
精品文档
不仅需要写出来,而且还要通过合适位置的输出,来判断程序是否按照自己预期的样子运行。

这个过程同样需要对同步机制有较好理解,才能理清楚。

做了这次lab,觉得自己对于同步机制又多了一层了解,而且代码和报告均是自己独立完成,没有参考网上前人的报告,觉得挺高兴的!
内容五:参考文献
[1]陈向群同步机制操作系统课件2014版
[2]linux同步机制网络博客
[3]小组成员:王丰condition的实现方式讨论.。

相关文档
最新文档