1、操作系统实验nachos01实验一 体验Nachos下的并发程序设计一、实验人员: 二、实验目的:对nachos进行熟悉,并初步体验nachos下的并发程序设计三、实验容:1、安装Nachos2、用C+实现双向有序链表;3、在nachos系统中使用所写的链表程序并演示一些并发错误四、实验步骤:1、 安装Nachos,具体细则如下下载code-linux.tar.gz并上传到服务器建立目录(推荐建立主目录下的nachos)cd到新建目录中tar zxvf code-linux.tar.gz的完整路径cd nachos-3.4/codemake2、 阅读材料阅读nachos-3.4/code/Ma
2、kefilenachos-3.4/code/Makefile.depnachos-3.4/code/Mmonnachos-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/thr
3、eads/threadtest.cc,了解nachos中线程的概念及其运作方式。3、 编写相关的dllist.h,dllist.cc,dllist-driver.cc文件,具体代码如下dllist.hclass DLLElement public:DLLElement( void *itemPtr, int sortKey ); / initialize a list elementDLLElement *next; / next element on list/ NULL if this is the lastDLLElement *prev; / previous element on l
4、ist/ NULL if this is the firstint key; / priority, for a sorted listvoid *item; / pointer to item on the list;class DLList public:DLList(); / initialize the listDLList(int type);DLList(); / de-allocate the listvoid Prepend(void *item); / add to head of list (set key = min_key-1)void Append(void *ite
5、m); / add to tail of list (set key = max_key+1)void *Remove(int *keyPtr); / remove from head of list/ set *keyPtr to key of the removed item/ return item (or NULL if list is empty)bool IsEmpty(); / return true if list has elements/ routines to put/get items on/off list in order (sorted by key)void S
6、ortedInsert(void *item, int sortKey);void *SortedRemove(int sortKey); / remove first item with key=sortKey/ return NULL if no such item existsprivate:DLLElement *first; / head of the list, NULL if emptyDLLElement *last; / last element of the list, NULL if emptyint err_type;Dllist.cc#include copyrigh
7、t.h#include dllist.h#include system.hDLLElement:DLLElement( void *itemPtr, int sortKey ) / initialize a list element item=itemPtr; key=sortKey; next=NULL; prev=NULL;DLList:DLList() / initialize the list first=NULL; last=NULL; err_type=0;DLList:DLList(int type) first=NULL; last=NULL; err_type=type;DL
8、List:DLList() / de-allocate the list while (Remove(NULL)!=NULL) ;void DLList:Prepend(void *item) / add to head of list (set key = min_key-1) DLLElement *elm=new DLLElement(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;
9、void DLList:Append(void *item) / add to tail of list (set key = max_key+1) DLLElement *elm=new DLLElement(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) / remove from head of list DLLElement
10、 *element; if (IsEmpty() return NULL; void *retitem; element=first; *keyPtr=first-key; if (err_type=1) printf(Remove errorn); currentThread-Yield(); retitem=element-item; if (first=last) first=NULL; last=NULL; else if (err_type=1) printf(Remove errorn); currentThread-Yield(); first=element-next; fir
11、st-prev=NULL; delete element; return retitem;bool DLList:IsEmpty() / return true if list has elements if (first=NULL)&(last=NULL) return true; else if(first!=NULL)&(last!=NULL) return false; else printf(error!either the first or the last is NULL!n); return false;void DLList:SortedInsert(void *item,
12、int sortKey) / routines to put/get items on/off list in order (sorted by key) DLLElement *insertItem=new DLLElement(item,sortKey); DLLElement *ptr=first; if (IsEmpty() first=insertItem; if (err_type=2) printf(SortedInsert error,first!=lastn); currentThread-Yield(); last=insertItem; else for (;ptr!=N
13、ULL; ptr=ptr-next) if (ptr-keysortKey) break; if (err_type=3) printf(SortedInsert error,the postion lostn); 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=insert
14、Item; first-prev=NULL; else ptr-prev-next=insertItem; insertItem-prev=ptr-prev; if (err_type=4) printf(SorteadInsert error,sort errorn); currentThread-Yield(); insertItem-next=ptr; ptr-prev=insertItem; void *DLList:SortedRemove(int sortKey) / remove first item with key=sortKey / return NULL if no su
15、ch item exists DLLElement *ptr=first; if (IsEmpty() return NULL; for (;ptr!=NULL; ptr=ptr-next) if (ptr-keysortKey) break; if (ptr=NULL) printf(Remove error!No such a key!); return NULL; else if (ptr=first) first=first-next; first-prev=NULL; else if (ptr=last) last=last-prev; last-next=NULL; else pt
16、r-prev-next=ptr-next; ptr-next-prev=ptr-prev; return ptr-item;Dllist-driver.cc#include #include copyright.h#include dllist.h#include system.h#include void Insert(int t,int n,DLList *dllist) int i,ll; srand(time(0); for (i=0; iSortedInsert(NULL,ll); printf(Thread %d : inserted key=%dn,t,ll); void Rem
17、ove(int t,int n,DLList *dllist) int i,keyll; for (i=0; iRemove(&keyll); printf(Thread %d : removed key=%dn,t,keyll); 4、将上述要的链表文件拷贝nachos-3.4/code/threads/中,修改nachos-3.4/code/Mmon中的THREAD_H、THREAD_C、THREAD_O,在nachos-3.4/code/threads/目录中依次执行make depend和make修改nachos-3.4/code/threads/threadtest.cc和nacho
18、s-3.4/code/threads/main.cc实现两个线程调用链表功能,重新编译threads子系统修改nachos-3.4/code/threads/threadtest.cc,在适当位置插入currentThread-Yield()调用以强制线程切换(注意相应文件中应该包含对外部变量currentThread的声明并include thread.h),重新编译threads子系统 MmonTHREAD_H =./threads/copyright.h ./threads/list.h ./threads/dllist.hTHREAD_C =./threads/main.cc ./th
19、reads/dllist.cc ./threads/dllist-driver.cc ./threads/list.cc THREAD_O =main.o dllist.o dllist-driver.o list.oMain.cc 添加线程数,结点个数,错误类型,以及参数的修改#ifdef THREADSextern int testnum;extern int threadnum;extern int n;extern int err_type;#endif#ifdef THREADS for (argc-, argv+; argc 0; argc -= argCount, argv +=
20、 argCount) argCount = 1; switch (argv01) case q: testnum = atoi(argv1); argCount+; break; case t: threadnum = atoi(argv1); argCount+; break; case n: n = atoi(argv1); argCount+; break; case e: err_type = atoi(argv1); argCount+; break; default: testnum = 1; break; ThreadTest();#endifThreadtest.cc 将双向链
21、表的功能嵌入,设置测试号为 2/ testnum is set in main.ccint testnum = 1,threadnum=1,n,err_type=0;DLList *dllist; voidDLListThread(int t) Insert(t,n,dllist); Remove(t,n,dllist);voidThreadTest2() DEBUG(t,Entering ThreadTest2); dllist=new DLList(err_type); for (int i=1; iFork(DLListThread,i); DLListThread(threadnum)
22、;/-/ ThreadTest/ Invoke a test routine./-voidThreadTest() switch (testnum) case 1: ThreadTest1(); break; case 2: ThreadTest2(); break; default: printf(No test specified.n); break; 5、 相关并发错误分析参照如下示例运行nachos./nachos q 2 t 2 n 2 e 0-q 2表示选择双向链表模式 -t为线程数-n 为插入结点数-e 为错误号 (1)无并发错误 ./nachos q 2 t 2 n 2 (2)
23、 在remove中,由于线程切换,使返回值指向出错./nachos q 2 t 2 n 4 e 1相关代码段: void *retitem; element=first; *keyPtr=first-key; if (err_type=1) printf(Remove errorn); currentThread-Yield(); retitem=element-item; (3) SortedInsert且链表为空时,由于进程切换,导致first与last指向有可能不一致。./nachos q 2 t 2 n 4 e 2相关代码段: if (IsEmpty() first=insertIte
24、m; if (err_type=2) printf(SortedInsert error,first!=lastn); currentThread-Yield(); last=insertItem; (4) SortedInsert时,将结点插入链表中时,由于进程切换,导致原来找到的结点位置丢失./nachos q 2 t 2 n 4 e 3相关代码段:for (;ptr!=NULL; ptr=ptr-next) if (ptr-keysortKey) break; if (err_type=3) printf(SortedInsert error,the postion lostn); cu
25、rrentThread-Yield(); (5) SortedInsert时,将结点插入链表中时,由于进程切换,导致结点间连接混乱./nachos q 2 t 2 n 4 e 4相关代码段: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
26、-next=insertItem; insertItem-prev=ptr-prev; if (err_type=4) printf(SorteadInsert error,sort errorn); 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