.
实验三操作系统实验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 EventBarrier{
public:
.
EventBarrier();
~EventBarrier();
void Wait();
void Signal();
void Complete();
int Waiters();
private:
bool state;
Condition *waits;
Condition *waitc;
Lock *barrier;
Lock *inbarrier;
int waiter;
};
#endif
https://www.doczj.com/doc/a116729386.html,
#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);
}
else
{
waitc->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 Alarm{
public:
Alarm();
~Alarm();
void Pause(int howLong);
void Wakeup();
int Getpausenum(); private:
List *queue;
int pausenum;
int leftime;
#endif
https://www.doczj.com/doc/a116729386.html,
#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;
}
else
{
oldLevel = interrupt->SetLevel(IntOff);
queue->SortedInsert(thread,ptime);
(void) interrupt->SetLevel(oldLevel);
break;
}
}
}
int
Alarm::Getpausenum()
{
return pausenum;
}
3.实现单个电梯
Elevator.h
class Elevator
{
public:
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: