操作系统实验nachos01.docx

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

操作系统实验nachos01.docx

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

操作系统实验nachos01.docx

操作系统实验nachos01

实验一体验Nachos下的并发程序设计

一、实验人员:

二、实验目的:

对nachos进行熟悉,并初步体验nachos下的并发程序设计

三、实验容:

1、安装Nachos

2、用C++实现双向有序链表;

3、在nachos系统中使用所写的链表程序并演示一些并发错误

四、实验步骤:

1、安装Nachos,具体细则如下

下载code-linux.tar.gz并上传到服务器

建立目录(推荐建立主目录下的nachos)

cd到新建目录中

tarzxvfcode-linux.tar.gz的完整路径

cdnachos-3.4/code

make

2、阅读材料

阅读nachos-3.4/code/Makefile

  nachos-3.4/code/Makefile.dep

  nachos-3.4/code/Mmon

  nachos-3.4/code/threads/Makefile

初步了解各Makefile的构成和相互关系。

阅读nachos-3.4/code/threads/main.cc了解nachos如何开始。

阅读nachos-3.4/code/threads/system.cc的Initialize函数中与debug相关的部分及nachos-3.4/code/threads/utility.cc了解DEBUG的实现与使用,以此进一步熟悉nachos系统。

阅读nachos-3.4/code/threads/threadtest.cc,了解nachos中线程的概念及其运作方式。

3、编写相关的dllist.h,dllist.cc,dllist-driver.cc文件,具体代码如下

dllist.h

classDLLElement{

public:

DLLElement(void*itemPtr,intsortKey);//initializealistelement

DLLElement*next;//nextelementonlist

//NULLifthisisthelast

DLLElement*prev;//previouselementonlist

//NULLifthisisthefirst

intkey;//priority,forasortedlist

void*item;//pointertoitemonthelist

};

classDLList{

public:

DLList();//initializethelist

DLList(inttype);

~DLList();//de-allocatethelist

voidPrepend(void*item);//addtoheadoflist(setkey=min_key-1)

voidAppend(void*item);//addtotailoflist(setkey=max_key+1)

void*Remove(int*keyPtr);//removefromheadoflist

//set*keyPtrtokeyoftheremoveditem

//returnitem(orNULLiflistisempty)

boolIsEmpty();//returntrueiflisthaselements

//routinestoput/getitemson/offlistinorder(sortedbykey)

voidSortedInsert(void*item,intsortKey);

void*SortedRemove(intsortKey);//removefirstitemwithkey==sortKey

//returnNULLifnosuchitemexists

private:

DLLElement*first;//headofthelist,NULLifempty

DLLElement*last;//lastelementofthelist,NULLifempty

interr_type;

};

 

Dllist.cc

#include"copyright.h"

#include"dllist.h"

#include"system.h"

DLLElement:

:

DLLElement(void*itemPtr,intsortKey)//initializealistelement

{

item=itemPtr;

key=sortKey;

next=NULL;

prev=NULL;

}

DLList:

:

DLList()//initializethelist

{

first=NULL;

last=NULL;

err_type=0;

}

DLList:

:

DLList(inttype)

{

first=NULL;

last=NULL;

err_type=type;

}

DLList:

:

~DLList()//de-allocatethelist

{

while(Remove(NULL)!

=NULL)

;

}

voidDLList:

:

Prepend(void*item)//addtoheadoflist(setkey=min_key-1)

{

DLLElement*elm=newDLLElement(item,0);

if(IsEmpty())

{

first=elm;

last=elm;

}

else

{

elm->key=first->key-1;

elm->next=first;

elm->prev=NULL;

first->prev=elm;

first=elm;

}

}

voidDLList:

:

Append(void*item)//addtotailoflist(setkey=max_key+1)

{

DLLElement*elm=newDLLElement(item,0);

if(IsEmpty())

{

first=elm;

last=elm;

}

else

{

elm->key=last->key+1;

elm->next=NULL;

elm->prev=last;

last->next=elm;

last=elm;

}

}

void*DLList:

:

Remove(int*keyPtr)//removefromheadoflist

{

DLLElement*element;

if(IsEmpty())

{

returnNULL;

}

void*retitem;

element=first;

*keyPtr=first->key;

if(err_type==1)

{

printf("Removeerror\n");

currentThread->Yield();

}

retitem=element->item;

if(first==last)

{

first=NULL;

last=NULL;

}

else

{

if(err_type==1)

{

printf("Removeerror\n");

currentThread->Yield();

}

first=element->next;

first->prev=NULL;

}

deleteelement;

returnretitem;

}

boolDLList:

:

IsEmpty()//returntrueiflisthaselements

{

if((first==NULL)&&(last==NULL))

returntrue;

elseif((first!

=NULL)&&(last!

=NULL))

returnfalse;

else

printf("error!

eitherthefirstorthelastisNULL!

\n");

returnfalse;

}

voidDLList:

:

SortedInsert(void*item,intsortKey)//routinestoput/getitemson/offlistinorder(sortedbykey)

{

DLLElement*insertItem=newDLLElement(item,sortKey);

DLLElement*ptr=first;

if(IsEmpty())

{

first=insertItem;

if(err_type==2)

{

printf("SortedInserterror,first!

=last\n");

currentThread->Yield();

}

last=insertItem;

}

else

{

for(;ptr!

=NULL;ptr=ptr->next)

if(ptr->key>sortKey)break;

if(err_type==3)

{

printf("SortedInserterror,thepostionlost\n");

currentThread->Yield();

}

if(ptr==NULL)

{

insertItem->prev=last;

last->next=insertItem;

last=insertItem;

last->next=NULL;

}

else

if(ptr==first)

{

insertItem->next=first;

first->prev=insertItem;

first=insertItem;

first->prev=NULL;

}

else

{

ptr->prev->next=insertItem;

insertItem->prev=ptr->prev;

if(err_type==4)

{

printf("SorteadInserterror,sorterror\n");

currentThread->Yield();

}

insertItem->next=ptr;

ptr->prev=insertItem;

}

}

}

void*DLList:

:

SortedRemove(intsortKey)//removefirstitemwithkey==sortKey

{//returnNULLifnosuchitemexists

DLLElement*ptr=first;

if(IsEmpty())

returnNULL;

for(;ptr!

=NULL;ptr=ptr->next)

if(ptr->key>sortKey)break;

if(ptr==NULL)

{

printf("Removeerror!

Nosuchakey!

");

returnNULL;

}

elseif(ptr==first)

{

first=first->next;

first->prev=NULL;

}

elseif(ptr==last)

{

last=last->prev;

last->next=NULL;

}

else

{

ptr->prev->next=ptr->next;

ptr->next->prev=ptr->prev;

}

returnptr->item;

}

Dllist-driver.cc

#include

#include"copyright.h"

#include"dllist.h"

#include"system.h"

#include

voidInsert(intt,intn,DLList*dllist)

{

inti,ll;

srand(time(0));

for(i=0;i

{

ll=rand()%101;

dllist->SortedInsert(NULL,ll);

printf("Thread%d:

insertedkey=%d\n",t,ll);

}

}

voidRemove(intt,intn,DLList*dllist)

{

inti,keyll;

for(i=0;i

{

dllist->Remove(&keyll);

printf("Thread%d:

removedkey=%d\n",t,keyll);

}

}

4、将上述要的链表文件拷贝nachos-3.4/code/threads/中,修改nachos-3.4/code/Mmon中的THREAD_H、THREAD_C、THREAD_O,在nachos-3.4/code/threads/目录中依次执行makedepend和make

修改nachos-3.4/code/threads/threadtest.cc和nachos-3.4/code/threads/main.cc实现两个线程调用链表功能,重新编译threads子系统

修改nachos-3.4/code/threads/threadtest.cc,在适当位置插入currentThread->Yield()调用以强制线程切换(注意相应文件中应该包含对外部变量currentThread的声明并includethread.h),重新编译threads子系统

Mmon

THREAD_H=../threads/copyright.h\

../threads/list.h\

../threads/dllist.h\

THREAD_C=../threads/main.cc\

../threads/dllist.cc\

../threads/dllist-driver.cc\

../threads/list.cc\

THREAD_O=main.odllist.odllist-driver.olist.o

Main.cc添加线程数,结点个数,错误类型,以及参数的修改

#ifdefTHREADS

externinttestnum;

externintthreadnum;

externintn;

externinterr_type;

#endif

#ifdefTHREADS

for(argc--,argv++;argc>0;argc-=argCount,argv+=argCount){

argCount=1;

switch(argv[0][1]){

case'q':

testnum=atoi(argv[1]);

argCount++;

break;

case't':

threadnum=atoi(argv[1]);

argCount++;

break;

case'n':

n=atoi(argv[1]);

argCount++;

break;

case'e':

err_type=atoi(argv[1]);

argCount++;

break;

default:

testnum=1;

break;

}

}

ThreadTest();

#endif

Threadtest.cc将双向链表的功能嵌入,设置测试号为2

//testnumissetinmain.cc

inttestnum=1,threadnum=1,n,err_type=0;

DLList*dllist;

void

DLListThread(intt)

{

Insert(t,n,dllist);

Remove(t,n,dllist);

}

void

ThreadTest2()

{

DEBUG('t',"EnteringThreadTest2");

dllist=newDLList(err_type);

for(inti=1;i

{

Thread*t=newThread("forkerthread");

t->Fork(DLListThread,i);

}

DLListThread(threadnum);

}

//----------------------------------------------------------------------

//ThreadTest

//Invokeatestroutine.

//----------------------------------------------------------------------

void

ThreadTest()

{

switch(testnum){

case1:

ThreadTest1();

break;

case2:

ThreadTest2();

break;

default:

printf("Notestspecified.\n");

break;

}

 

5、相关并发错误分析

参照如下示例运行nachos

./nachos–q2–t2–n2–e0

-q2表示选择双向链表模式

-t为线程数

-n为插入结点数

-e为错误号

(1)无并发错误

./nachos–q2–t2–n2

(2)在remove中,由于线程切换,使返回值指向出错

./nachos–q2–t2–n4–e1

相关代码段:

void*retitem;

element=first;

*keyPtr=first->key;

if(err_type==1)

{

printf("Removeerror\n");

currentThread->Yield();

}

retitem=element->item;

(3)SortedInsert且链表为空时,由于进程切换,导致first与last指向有可能不一致。

./nachos–q2–t2–n4–e2

相关代码段:

if(IsEmpty())

{

first=insertItem;

if(err_type==2)

{

printf("SortedInserterror,first!

=last\n");

currentThread->Yield();

}

last=insertItem;

}

(4)SortedInsert时,将结点插入链表中时,由于进程切换,导致原来找到的结点位置丢失

./nachos–q2–t2–n4–e3

相关代码段:

for(;ptr!

=NULL;ptr=ptr->next)

if(ptr->key>sortKey)break;

if(err_type==3)

{

printf("SortedInserterror,thepostionlost\n");

currentThread->Yield();

}

(5)SortedInsert时,将结点插入链表中时,由于进程切换,导致结点间连接混乱

./nachos–q2–t2–n4–e4

相关代码段:

if(ptr==NULL)

{

insertItem->prev=last;

last->next=insertItem;

last=insertItem;

last->next=NULL;

}

else

if(ptr==first)

{

insertItem->next=first;

first->prev=insertItem;

first=insertItem;

first->prev=NULL;

}

else

{

ptr->prev->next=insertItem;

insertItem->prev=ptr->prev;

if(err_type==4)

{

printf("SorteadInserterror,sorterror\n");

currentThread->Yield();

}

insertItem->next=ptr;

ptr->prev=insertItem;

}

实验心得:

(1)在dllist-driver.cc中引用stdlib库时,若将库的引用的次序置于system.h与time.h之后,将可能引发声明的相关问题。

(2)在引用外部变量以及外部函数的时候必须要用extern声明。

(3)关于双向链表操作的代码其实并不难,关键是在对双向链表进行操作的时候,在适当的位置进行切换会引起不同的并发错误。

通过本次实验,熟悉了nachos中与本次实验相关的容,了解了线程的切换以及线程切换可能引发的并发错误。

 

实验分工:

实验代码编写三人先各自编写,最后讨论得出最终代码。

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

当前位置:首页 > 医药卫生 > 基础医学

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

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