实验三-操作系统实验Nacho(共11页).doc
-
资源ID:7918699
资源大小:140KB
全文页数:11页
- 资源格式: DOC
下载积分:20金币
快捷下载
会员登录下载
微信登录下载
三方登录下载:
微信扫一扫登录
友情提示
2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
|
实验三-操作系统实验Nacho(共11页).doc
精选优质文档-倾情为你奉上实验三 操作系统实验Nacho一、实验人员: 二、实验目的:本次实验的目的在于掌握使用nachos中的线程序解决较为复杂的并发问题。实验内容分三部分:实现事件栅栏原语并进行正确性测试;实现闹钟原语并进行正确性测试;利用事件栅栏和闹钟原语来解决电梯问题(详细内容请看nachos-labs.pdf)。三、实验内容:1.实现事件栅栏原语2.实现闹钟原语3. 解决电梯问题四、实验步骤:1. 实现事件栅栏原语EventBarrier.h#ifndef EVENTBARRIER_H#define EVENTBARRIER_H#include "synch-sem.h"#define SIGNALED 1 #define UNSIGNALED 0 class EventBarrierpublic:EventBarrier();EventBarrier();void Wait();void Signal();void Complete();int Waiters();private:bool state;Condition *waits;Condition *waitc;Lock *barrier;Lock *inbarrier;int waiter;#endifEventBarrier.cc#include "EventBarrier.h"#include "thread.h"EventBarrier:EventBarrier()waits=new Condition("waitsignal");waitc=new Condition("waitcomplete");barrier=new Lock("barrier");inbarrier=new Lock("inbarrier");state=UNSIGNALED;waiter=0;EventBarrier:EventBarrier()delete waits;delete waitc;void EventBarrier:Wait()barrier->Acquire();waiter+;while(state=UNSIGNALED)waits->Wait(barrier);barrier->Release();void EventBarrier:Signal()barrier->Acquire();state=SIGNALED;waits->Broadcast(barrier);barrier->Release();inbarrier->Acquire();waitc->Wait(inbarrier);inbarrier->Release();state=UNSIGNALED;void EventBarrier:Complete()inbarrier->Acquire();waiter-;if(waiter=0)waitc->Broadcast(inbarrier);elsewaitc->Wait(inbarrier);inbarrier->Release();int EventBarrier:Waiters()return waiter;2. 实现闹钟原语Alarm.h#ifndef ALARM_H#define ALARM_H#include "system.h"#include "list.h"class Alarmpublic:Alarm();Alarm();void Pause(int howLong);void Wakeup();int Getpausenum();private:List *queue;int pausenum;int leftime;#endifAlarm.cc#include "system.h"#include "thread.h"#include "Alarm.h"extern Alarm *alarm;void check(int which)while(alarm->Getpausenum()!=0)currentThread->Yield();currentThread->Finish();Alarm:Alarm()queue=new List();pausenum=0;Alarm:Alarm()queue->List();void Alarm:Pause(int howLong)Thread *t;pausenum+;if(pausenum=1)t=new Thread("forked thread");t->Fork(check,0);if(howLong<=0)return;leftime=stats->totalTicks+howLong*TimerTicks*10000;IntStatus oldlevel=interrupt->SetLevel(IntOff);queue->SortedInsert(currentThread,leftime);currentThread->Sleep();(void) interrupt->SetLevel(oldlevel);void Alarm:Wakeup()Thread *thread; int ptime=-1;IntStatus oldLevel = interrupt->SetLevel(IntOff); thread = (Thread *)queue->SortedRemove(&ptime); (void) interrupt->SetLevel(oldLevel); while( thread != NULL ) if(stats->totalTicks>=ptime)scheduler->ReadyToRun(thread);pausenum-;oldLevel = interrupt->SetLevel(IntOff); thread = (Thread *)queue->SortedRemove(&ptime); (void) interrupt->SetLevel(oldLevel);continue; elseoldLevel = interrupt->SetLevel(IntOff); queue->SortedInsert(thread,ptime); (void) interrupt->SetLevel(oldLevel); break; intAlarm:Getpausenum()return pausenum;3.实现单个电梯Elevator.hclass Elevatorpublic:Elevator(char *debugname,int numfloors,int myid); Elevator(); char *getName() return name; void OpenDoors(); /*电梯开门*/ void CloseDoors(int i); /*电梯关门*/ bool VisitFloor(int floor); /*查看电梯是否访问某层*/ bool Enter(int id); /*乘客进入电梯*/ void Exit(int id); /*乘客离开电梯*/ void RequestFloor(int floor); /*乘客阻塞在电梯内部*/ int GetID()return id; int GetFloor()return currentfloor; int GetState()return states;void SetState(int i); /*设置电梯状态*/ bool IFEMPTY(); /*电梯是否为空*/ void GoUp(); /*电梯上行*/ void GoDown(); /*电梯下行*/ private: char *name; int id; int numFloors;/*电梯所能到达的最大楼层*/ int currentfloor; /*目前所在楼层*/ int occupancy; /*目前乘客数目*/ int MaxNumber;/*最大乘客数目*/ int states;/*电梯状态*/ EventBarrier *eventbarrier;/*电梯栅栏*/ bool *ifvisitfloor;/*判断电梯是否停留某楼层的数组*/ Lock *occlock; ;class Building public: Building(char *debugname,int numfloors,int numelevators); Building(); char *getName() return name; void CallUp(int fromFloor); void CallDown(int fromFloor); Elevator *AwaitUp(int fromFloor); /*乘客等待,阻塞,返回电梯指针*/ Elevator *AwaitDown(int fromFloor); /*乘客等待,阻塞,返回电梯指针*/ bool GetDownLight(int floor)return DownLightfloor; bool GetUpLight(int floor)return UpLightfloor; void SetDownLight(int t,bool i); void SetUpLight(int t,bool i);void WakeUp();void WakeDown();Elevator *TellElevator(); private: char *name; int NumElevators;/*电梯数目*/ int NumFloors;/*楼层数目*/ EventBarrier *eventbarrier_up;/*上行栅栏*/EventBarrier *eventbarrier_down;/*下行栅栏*/Elevator *elevator;/*一个电梯*/bool *DownLight;/*楼层下行按键*/bool *UpLight;/*楼层上行按键*/;Elevator.cc#include "synch-sleep.h"#include "system.h"#include "EventBarrier.h"EventBarrier:EventBarrier()eventlock=new Lock("eventlcok");complete=new Condition("complete");signal=new Condition("signal");SIGNALED=false;waiters_count=0;EventBarrier:EventBarrier()delete eventlock;delete signal;delete complete;void EventBarrier:Wait()eventlock->Acquire(); waiters_count+;while(!SIGNALED)/*如果事件栅状态是UNSIGNALED,则阻塞*/signal->Wait(eventlock);eventlock->Release(); void EventBarrier:Signal()eventlock->Acquire(); SIGNALED=true;/*设置事件栅栏的状态为SIGNALED*/printf("n set SIGNALED=true,waiting for all forks WakeUp"); signal->Broadcast(eventlock);/*唤醒所有阻塞于Signal的线程*/complete->Wait(eventlock);/*阻塞于Complete*/printf("n has already signaled all waiting forks");SIGNALED=false;/*恢复事件栅栏的状态为UNSIGNALED*/printf("n has already reset SIGNALED=falsen");eventlock->Release(); void EventBarrier:Complete()eventlock->Acquire();waiters_count-; if(waiters_count=0)/*最后一个应答,唤醒所有阻塞在complete的线程*/complete->Broadcast(eventlock);else if(waiters_count>0)/*并非最后一个应答,阻塞在complete*/complete->Wait(eventlock);else printf("n waiters_count error!");eventlock->Release(); int EventBarrier:Waiters()return waiters_count;五、实验结果1.事件栅栏测试结果2.闹钟测试结果3.电梯测试结果普通情况电梯满六、实验总结本次实验关于电梯的程序难度较大,特别是电梯部分。电梯部分只是初步实现了部分的功能,只有单部电梯且最多9个rider才能正常运转。本次实验问题非常多,主要的有如下几点:1.事件栅栏中要注意线程被唤醒时,返回wait 时,要处于一个while循环中,否则可能造成信号丢失。2.闹钟原语中,wait要在system.cc中的时间中断处理函数中调用。3.最初写的电梯代码结果总是停在电梯开门的情况,后来参考了别人的代码发现许多变量需要加锁。最终写出来的电梯还是比较脆弱的,只有在线程小于9的时候才可以正常运行,而且电梯满的时候有时候会有问题。专心-专注-专业