实验三操作系统实验Nacho.docx

上传人:b****6 文档编号:7036972 上传时间:2023-01-16 格式:DOCX 页数:14 大小:118.21KB
下载 相关 举报
实验三操作系统实验Nacho.docx_第1页
第1页 / 共14页
实验三操作系统实验Nacho.docx_第2页
第2页 / 共14页
实验三操作系统实验Nacho.docx_第3页
第3页 / 共14页
实验三操作系统实验Nacho.docx_第4页
第4页 / 共14页
实验三操作系统实验Nacho.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

实验三操作系统实验Nacho.docx

《实验三操作系统实验Nacho.docx》由会员分享,可在线阅读,更多相关《实验三操作系统实验Nacho.docx(14页珍藏版)》请在冰豆网上搜索。

实验三操作系统实验Nacho.docx

实验三操作系统实验Nacho

实验三操作系统实验Nacho

一、实验人员:

二、实验目的:

本次实验的目的在于掌握使用nachos中的线程序解决较为复杂的并发问题。

实验内容分三部分:

实现事件栅栏原语并进行正确性测试;实现闹钟原语并进行正确性测试;利用事件栅栏和闹钟原语来解决电梯问题(详细内容请看nachos-labs.pdf)。

三、实验内容:

1.实现事件栅栏原语

2.实现闹钟原语

3.解决电梯问题

四、实验步骤:

1.实现事件栅栏原语

EventBarrier.h

#ifndefEVENTBARRIER_H

#defineEVENTBARRIER_H

#include"synch-sem.h"

#defineSIGNALED1

#defineUNSIGNALED0

classEventBarrier{

public:

EventBarrier();

~EventBarrier();

voidWait();

voidSignal();

voidComplete();

intWaiters();

private:

boolstate;

Condition*waits;

Condition*waitc;

Lock*barrier;

Lock*inbarrier;

intwaiter;

};

#endif

EventBarrier.cc

#include"EventBarrier.h"

#include"thread.h"

EventBarrier:

:

EventBarrier()

{

waits=newCondition("waitsignal");

waitc=newCondition("waitcomplete");

barrier=newLock("barrier");

inbarrier=newLock("inbarrier");

state=UNSIGNALED;

waiter=0;

}

EventBarrier:

:

~EventBarrier()

{

deletewaits;

deletewaitc;

}

voidEventBarrier:

:

Wait()

{

barrier->Acquire();

waiter++;

while(state==UNSIGNALED)

waits->Wait(barrier);

barrier->Release();

}

voidEventBarrier:

:

Signal()

{

barrier->Acquire();

state=SIGNALED;

waits->Broadcast(barrier);

barrier->Release();

inbarrier->Acquire();

waitc->Wait(inbarrier);

inbarrier->Release();

state=UNSIGNALED;

}

voidEventBarrier:

:

Complete()

{

inbarrier->Acquire();

waiter--;

if(waiter==0)

{

waitc->Broadcast(inbarrier);

}

else

{

waitc->Wait(inbarrier);

}

inbarrier->Release();

}

intEventBarrier:

:

Waiters()

{

returnwaiter;

}

2.实现闹钟原语

Alarm.h

#ifndefALARM_H

#defineALARM_H

#include"system.h"

#include"list.h"

classAlarm{

public:

Alarm();

~Alarm();

voidPause(inthowLong);

voidWakeup();

intGetpausenum();

private:

List*queue;

intpausenum;

intleftime;

};

#endif

Alarm.cc

#include"system.h"

#include"thread.h"

#include"Alarm.h"

externAlarm*alarm;

voidcheck(intwhich)

{

while(alarm->Getpausenum()!

=0)

{

currentThread->Yield();

}

currentThread->Finish();

}

Alarm:

:

Alarm()

{

queue=newList();

pausenum=0;

}

Alarm:

:

~Alarm()

{

queue->~List();

}

voidAlarm:

:

Pause(inthowLong)

{

Thread*t;

pausenum++;

if(pausenum==1)

{

t=newThread("forkedthread");

t->Fork(check,0);

}

if(howLong<=0)

return;

leftime=stats->totalTicks+howLong*TimerTicks*10000;

IntStatusoldlevel=interrupt->SetLevel(IntOff);

queue->SortedInsert(currentThread,leftime);

currentThread->Sleep();

(void)interrupt->SetLevel(oldlevel);

}

voidAlarm:

:

Wakeup()

{

Thread*thread;

intptime=-1;

IntStatusoldLevel=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()

{

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

{

public:

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();

private:

char*name;

intNumElevators;/*电梯数目*/

intNumFloors;/*楼层数目*/

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=newLock("eventlcok");

complete=newCondition("complete");

signal=newCondition("signal");

SIGNALED=false;

waiters_count=0;

}

EventBarrier:

:

~EventBarrier()

{

deleteeventlock;

deletesignal;

deletecomplete;

}

voidEventBarrier:

:

Wait()

{

eventlock->Acquire();

waiters_count++;

while(!

SIGNALED)/*如果事件栅状态是UNSIGNALED,则阻塞*/

signal->Wait(eventlock);

eventlock->Release();

}

voidEventBarrier:

:

Signal()

{

eventlock->Acquire();

SIGNALED=true;/*设置事件栅栏的状态为SIGNALED*/

//printf("\nsetSIGNALED=true,waitingforallforksWakeUp");

signal->Broadcast(eventlock);/*唤醒所有阻塞于Signal的线程*/

complete->Wait(eventlock);/*阻塞于Complete*/

//printf("\nhasalreadysignaledallwaitingforks");

SIGNALED=false;/*恢复事件栅栏的状态为UNSIGNALED*/

//printf("\nhasalreadyresetSIGNALED=false\n");

eventlock->Release();

}

voidEventBarrier:

:

Complete()

{

eventlock->Acquire();

waiters_count--;

if(waiters_count==0)/*最后一个应答,唤醒所有阻塞在complete的线程*/

complete->Broadcast(eventlock);

elseif(waiters_count>0)/*并非最后一个应答,阻塞在complete*/

complete->Wait(eventlock);

else

printf("\nwaiters_counterror!

");

eventlock->Release();

}

intEventBarrier:

:

Waiters()

{

returnwaiters_count;

}

五、实验结果

1.事件栅栏测试结果

2.闹钟测试结果

3.电梯测试结果

普通情况

电梯满

六、实验总结

本次实验关于电梯的程序难度较大,特别是电梯部分。

电梯部分只是初步实现了部分的功能,只有单部电梯且最多9个rider才能正常运转。

本次实验问题非常多,主要的有如下几点:

1.事件栅栏中要注意线程被唤醒时,返回wait时,要处于一个while循环中,否则可能造成信号丢失。

2.闹钟原语中,wait要在system.cc中的时间中断处理函数中调用。

3.最初写的电梯代码结果总是停在电梯开门的情况,后来参考了别人的代码发现许多变量需要加锁。

最终写出来的电梯还是比较脆弱的,只有在线程小于9的时候才可以正常运行,而且电梯满的时候有时候会有问题。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 总结汇报

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1