nachos系统实验报告实验三Word格式.docx
《nachos系统实验报告实验三Word格式.docx》由会员分享,可在线阅读,更多相关《nachos系统实验报告实验三Word格式.docx(23页珍藏版)》请在冰点文库上搜索。
实现应解决注意公平性与饥饿问题。
4)Elevator:
实现Elevator类,并解决3个并发问题
、a)一个电梯,电梯容量无限。
、b)一个电梯,电梯容量有限。
a)c)多个电梯。
b)
三.实验结果
1.EventBarrier
类定义:
主要函数
1)Wait():
线程挂起待事件被signal,当事件已经处于signaled状态时直接return
2)Signal():
线程通知所有等待事件的线程。
并且挂起等待所有调用Wait()的线程结束操作并调用Complete()通知此线程(包括在挂起过程中调用Wait()的线程)。
3)Complete():
当所有Wait()线程都完成操作调用Complete后通知Signal线程,此线程已经完成操作,并且的等地其它线程response。
测试结果:
测试中主线程来释放Signal信号。
另4个线程做为等待线程,名字分别为Thread1~4。
Thread1,2在主线程Signal之前就调用Wait()函数,Thread3,4在事件被标志Signaled状态时才调用Wait()。
最终结果如下图所示,事件在四个线程都response自后才改变状态,四个线程个主线程都运行正确。
Thread
1,2
进入等待
signal事件
Thread3,4直接过Barrier。
完成操作进入complete等待
Thread1,2进入complete等待。
通知所有正在等待response的线程所有线程都已经complete
2.AlarmClock
类定义
1)Pause(inthowLong):
让事件停止howLong个时间单位。
调用了系统自带的函数interrupt->
Schedule函数,在howLong时间后调用TimeUP(int0)函数。
并将中断的发生时间totalTicks+howLong当做此线程的优先级将其挂起,确保每次alarmClock唤醒的线程是设置闹钟最早的线程。
2)TimeUP(intNoUse):
用于当做中断发生时的调用函数,函数中的alarmClock为全局闹钟变量。
参数没有任何作用。
3)ThreadRestart():
一个闹钟中断到来。
唤醒对应线程(最早线程),将其加入就绪队列。
共七个线程,每个线程设置的howLong为1~200随即数。
已运行多次进行检验。
其中一次结果如下图所示。
每个线程在正确的时间结束闹钟进入就绪队列。
每次时钟中断增加事件随机
Thread0,184
alarmend
Thread3,201
Thread2,271
Thread1,284
Thread6,289
Thread4,325
Thread5,400
3.Bridge
供Bridge模块使用的静态全局变量
Bridge采用的是先到先进的政策,若方向为1的车进桥,此时桥上只有1辆方向为1的车,但对面有方向为0的车在等待时,此车也进入等待。
以此达到公平和防止饿死,因为不会用车辆处于一直等待的状态。
1)ArriveBridge(intdir):
当桥上由3辆车时:
线程直接挂起。
当桥上由1,2辆车时:
若线程方向与桥的方向相反,线程挂起
若线程方向与桥的方向相同但对面由车等待,则线程挂起
当桥上没有车时:
线程直接通过
2)voidExitBridge(intdir):
当没有车等待时直接exit。
有车等待时:
当桥上有1辆车时:
等待的车方向一定相反,按先后顺序唤醒1~3辆方向与此线程方向相反的车。
当桥上有2辆车时:
因为此时等待队列下一辆车不可能与其方向相同。
所以当桥上车辆为2辆时不用处理。
当桥上有3两车时:
若等待队列下一辆车方向相同,车唤醒下一辆车。
创造6两车,每辆车的方向为随机0或1。
已检验多次,其中一次截图如下。
结果正确。
//从生成的车辆可以看出2~6号车将被挂起。
1号车exit桥,唤醒下面3辆方向与其相反的车辆
2号车出桥并唤醒5号车
3号车出桥唤醒6号车
除了随机的测试之外还测试了一些具体的情况如:
car1,dir0car2,dir1car3,dir0car4,dir1car5,dir0car6,dir1
car1,dir0car2,dir0car3,dir0car4,dir0car5,dir0car6,dir0
最终结果都显示正确。
4.Elevator
Elevator代码较多,下面按运行顺序进行介绍。
首先介绍Elevator的运行规则:
1)当Elevator无人且无人等待此电梯时,电梯自动回到第1层。
当电梯在第一无任何需要时,电梯自动进入就绪态,让别的线程运行。
2)当电梯运行的方向上还有人等待进入电梯(不分进入的方向)时,电梯继续运行,直到电梯运行的方向上没有人要进入(或电梯满人)和退出为止,电梯改变方向。
3)电梯先出后进,且进来的人必须全都完成RequsetFloor()之后电梯才能关门。
4)当有多个电梯时,用GetClosestElevator()函数来选择一个最近的电梯。
计算远近时,假设此时电梯都按自己的方向运行到底之后才转变方向来确定
电梯到达此楼需跨过多少楼层来当做距离。
函数介绍:
电梯循环运行的Run()函数:
1.无容量限制的电梯,building有3层,共7个人测试结果如下每个人的开始层数和目的层数都是随机的。
结果正确
2.1个电梯,容量为3,building有10层,共4个人。
每个人一开始都在第三层等待。
结果截图如下。
除此实验外。
还运行了多次building有3层,共10个人的测试程序
(截图太长),结果正确。
四个人都从第3层出发,电梯容量为3
Rider3因为电梯满人而没进成功
Rider1,2,4,RequstFloor
Rider3重新call一次
下次目的地选择第5层。
到达第六层后3个人一起下电梯
最后载Rider3
电梯不需要了回到第一层。
Elevator结束
3.多个电梯:
2个电梯,4个人。
两人先选择电梯后,后两人在电梯位置改变后在进入building进行选择电梯。
除此之外还运行了3个电梯,每个电梯3容量,共20人的测试几次。
四.实验总结
∙EventBarrier是用于某线程在进行某些操作前需要某个事件或条件先得到满足后再执行的情况下使用。
如ELevator实现中某层等待的人要进入电梯中的情况。
∙因为Nachos的时间只有在线程调用Intrrupt:
:
SetLeve或Thread:
Sleep(Intrrupt:
Idle)函数时才会前进。
所以Nachos的时钟中断只可能在这调用可这两个函数的时候产生。
∙Bridge可以想象成总线传输数据一般,一次只能传输某个方向的数据,且传输的数据大小有限(OneVehicle代表一个单位数据)。
◦Bridge用先进现出的方法很大程度上影响了多线程的运行效率,lock的覆盖的范围也太大同时影响效率。
在很多情况下即使对面有车先等着的时候这里也可以过桥,有很大改进空间。
∙Elevator是到现在为止最复杂的多线程并行处理。
在处理过程中发生很多错误。
如在拥有lock的情况下还用EventBarrier将其挂起等等。
Elevator的实现让我对多线程的同步和互斥由了更深了了解和掌握。
◦Elevator的策略也不好,没有在有容量的情况下解决饥饿问题,电梯的搭乘策略会造成饿死。
可以按等待的人按电梯的时间来分配优先级优化电梯的选择搭乘算法。
在多电梯情况下更需要电梯选择策略来提高多个电梯的效率,避免个别几个电梯被过多使用,而另几个处于较闲的状态,使整体效率下降。