实验三操作系统实验NachoWord文件下载.docx
《实验三操作系统实验NachoWord文件下载.docx》由会员分享,可在线阅读,更多相关《实验三操作系统实验NachoWord文件下载.docx(14页珍藏版)》请在冰豆网上搜索。
intWaiters();
private:
boolstate;
Condition*waits;
Condition*waitc;
Lock*barrier;
Lock*inbarrier;
intwaiter;
};
#endif
EventBarrier.cc
EventBarrier.h"
thread.h"
EventBarrier:
:
EventBarrier()
{
waits=newCondition("
waitsignal"
);
waitc=newCondition("
waitcomplete"
barrier=newLock("
barrier"
inbarrier=newLock("
inbarrier"
state=UNSIGNALED;
waiter=0;
}
~EventBarrier()
deletewaits;
deletewaitc;
voidEventBarrier:
Wait()
barrier->
Acquire();
waiter++;
while(state==UNSIGNALED)
waits->
Wait(barrier);
Release();
Signal()
state=SIGNALED;
waits->
Broadcast(barrier);
inbarrier->
waitc->
Wait(inbarrier);
Complete()
waiter--;
if(waiter==0)
{
waitc->
Broadcast(inbarrier);
}
else
intEventBarrier:
Waiters()
returnwaiter;
2.实现闹钟原语
Alarm.h
#ifndefALARM_H
#defineALARM_H
system.h"
list.h"
classAlarm{
Alarm();
~Alarm();
voidPause(inthowLong);
voidWakeup();
intGetpausenum();
List*queue;
intpausenum;
intleftime;
Alarm.cc
Alarm.h"
externAlarm*alarm;
voidcheck(intwhich)
while(alarm->
Getpausenum()!
=0)
currentThread->
Yield();
currentThread->
Finish();
Alarm:
Alarm()
queue=newList();
pausenum=0;
~Alarm()
queue->
~List();
voidAlarm:
Pause(inthowLong)
Thread*t;
pausenum++;
if(pausenum==1)
t=newThread("
forkedthread"
t->
Fork(check,0);
if(howLong<
return;
leftime=stats->
totalTicks+howLong*TimerTicks*10000;
IntStatusoldlevel=interrupt->
SetLevel(IntOff);
SortedInsert(currentThread,leftime);
Sleep();
(void)interrupt->
SetLevel(oldlevel);
Wakeup()
Thread*thread;
intptime=-1;
IntStatusoldLevel=interrupt->
thread=(Thread*)queue->
SortedRemove(&
ptime);
SetLevel(oldLevel);
while(thread!
=NULL)
if(stats->
totalTicks>
=ptime)
{
scheduler->
ReadyToRun(thread);
pausenum--;
oldLevel=interrupt->
thread=(Thread*)queue->
(void)interrupt->
continue;
}
else
queue->
SortedInsert(thread,ptime);
break;
int
Getpausenum()
returnpausenum;
3.实现单个电梯
Elevator.h
classElevator
public:
Elevator(char*debugname,intnumfloors,intmyid);
~Elevator();
char*getName(){returnname;
}
voidOpenDoors();
/*电梯开门*/
voidCloseDoors(inti);
/*电梯关门*/
boolVisitFloor(intfloor);
/*查看电梯是否访问某层*/
boolEnter(intid);
/*乘客进入电梯*/
voidExit(intid);
/*乘客离开电梯*/
voidRequestFloor(intfloor);
/*乘客阻塞在电梯内部*/
intGetID(){returnid;
}
intGetFloor(){returncurrentfloor;
intGetState(){returnstates;
voidSetState(inti);
/*设置电梯状态*/
boolIFEMPTY();
/*电梯是否为空*/
voidGoUp();
/*电梯上行*/
voidGoDown();
/*电梯下行*/
private:
char*name;
intid;
intnumFloors;
/*电梯所能到达的最大楼层*/
intcurrentfloor;
/*目前所在楼层*/
intoccupancy;
/*目前乘客数目*/
intMaxNumber;
/*最大乘客数目*/
intstates;
/*电梯状态*/
EventBarrier*eventbarrier;
/*电梯栅栏*/
bool*ifvisitfloor;
/*判断电梯是否停留某楼层的数组*/
Lock*occlock;
classBuilding
Building(char*debugname,intnumfloors,intnumelevators);
~Building();
char*getName(){returnname;
voidCallUp(intfromFloor);
voidCallDown(intfromFloor);
Elevator*AwaitUp(intfromFloor);
/*乘客等待,阻塞,返回电梯指针*/
Elevator*AwaitDown(intfromFloor);
/*乘客等待,阻塞,返回电梯指针*/
boolGetDownLight(intfloor){returnDownLight[floor];
boolGetUpLight(intfloor){returnUpLight[floor];
voidSetDownLight(intt,booli);
voidSetUpLight(intt,booli);
voidWakeUp();
voidWakeDown();
Elevator*TellElevator();
intNumElevators;
/*电梯数目*/
intNumFloors;
/*楼层数目*/
EventBarrier*eventbarrier_up;
/*上行栅栏*/
EventBarrier*eventbarrier_down;
/*下行栅栏*/
Elevator*elevator;
/*一个电梯*/
bool*DownLight;
/*楼层下行按键*/
bool*UpLight;
/*楼层上行按键*/
Elevator.cc
synch-sleep.h"
eventlock=newLock("
eventlcok"
complete=newCondition("
complete"
signal=newCondition("
signal"
SIGNALED=false;
waiters_count=0;
deleteeventlock;
deletesignal;
deletecomplete;
eventlock->
waiters_count++;
while(!
SIGNALED)/*如果事件栅状态是UNSIGNALED,则阻塞*/
signal->
Wait(eventlock);
SIGNALED=true;
/*设置事件栅栏的状态为SIGNALED*/
//printf("
\nsetSIGNALED=true,waitingforallforksWakeUp"
Broadcast(eventlock);
/*唤醒所有阻塞于Signal的线程*/
complete->
/*阻塞于Complete*/
\nhasalreadysignaledallwaitingforks"
/*恢复事件栅栏的状态为UNSIGNALED*/
\nhasalreadyresetSIGNALED=false\n"
waiters_count--;
if(waiters_count==0)/*最后一个应答,唤醒所有阻塞在complete的线程*/
complete->
elseif(waiters_count>
0)/*并非最后一个应答,阻塞在complete*/
printf("
\nwaiters_counterror!
"
returnwaiters_count;
五、实验结果
1.事件栅栏测试结果
2.闹钟测试结果
3.电梯测试结果
普通情况
电梯满
六、实验总结
本次实验关于电梯的程序难度较大,特别是电梯部分。
电梯部分只是初步实现了部分的功能,只有单部电梯且最多9个rider才能正常运转。
本次实验问题非常多,主要的有如下几点:
1.事件栅栏中要注意线程被唤醒时,返回wait时,要处于一个while循环中,否则可能造成信号丢失。
2.闹钟原语中,wait要在system.cc中的时间中断处理函数中调用。
3.最初写的电梯代码结果总是停在电梯开门的情况,后来参考了别人的代码发现许多变量需要加锁。
最终写出来的电梯还是比较脆弱的,只有在线程小于9的时候才可以正常运行,而且电梯满的时候有时候会有问题。