logo资料库

体验Nachos下的并 发程序设计 实验报告.doc

第1页 / 共9页
第2页 / 共9页
第3页 / 共9页
第4页 / 共9页
第5页 / 共9页
第6页 / 共9页
第7页 / 共9页
第8页 / 共9页
资料共9页,剩余部分请下载后查看
实验一 体验 Nachos 下的并发程序设计 一、小组成员及分工 a:main.cc 的修改、threadtest.cc 的修改和实验报告 b:dllist.cc 的实现 c:dllist-driver.cc 的实现和实验报告的完成 d:dllist.h 的实现和 Makefile.common 的修改 二、实验目的 对 nachos 进行熟悉,并初步体验 nachos 下的并发程序设计。 三、实验内容 1.安装 nachos; 2.用 C++实现双向有序链表; 3.在 nachos 系统中使用你所写的链表程序并演示一些并发错误 四、实验步骤 1.首先明确 Nachos 各部分的关系 在~/nachos/nachos-3.4/code/下有一个 Makefile.common,在 code/的各个子目录下的 Makefile 都继承这个 Makefile.common。通过阅读 main.cc 知道,main 函数一旦启动, 立即调用 Initialize,进行初始化的操作,然后对相应的参数进行处理,之后在分模块进 行相应模块下的函数调用,执行相应的功能。 2.编写相应的函数 实验要求利用对双向链表的操作来演示并发程序可能出现的错误,首先需要实现双 向链表 dllist,包括 dllist.h,dllist.cc。当 DLList 类实现后,需要编写链表驱动函数 Insert 和 Remove 来对链表进行驱动。通过改写 threadtest.cc,使得多个线程在没有进行任何 互斥操作的情况下对同一数据结构进行操作,在这个过程中就可能出现并发错误。改写 Makefile.common 和 main.cc。 3.详细设计 a)dllist.h(~/nachos/nachos-3.4/code/threads/) 类 DLList 的声明 class DLLElement { public: DLLElement(void *itemPtr,int sortKey);//initialize a list element DLLElement *next;//next element on list DLLElement *prev;//previous element on list int key; void *item; }; class DLList { public: DLList();//initialize the list DLList(int type); ~DLList();//de-allocate the list
void Prepend(void *item);//add to head of list void Append(void *item);//add to tail of list void *Remove(int *keyPtr);//remove frome head of list bool IsEmpty();//return true if list has elements void SortedInsert(void *item,int sortKey); void *SortedRemove(int sortKey);//remove first item with key==sortKey private: DLLElement *first; DLLElement *last; int yield_type;//different yield positon }; b) dllist.cc(~/nachos/nachos-3.4/code/threads/) 类 DLList 方法的实现,其中核心操作 Remove,SortedInsert。 //---------------------------------------------------------------------- // DLList::Remove Remove the first "item" from the front of the dllist. // // // Returns: // Pointer to removed item, NULL if nothing on the list. //---------------------------------------------------------------------- void * DLList::Remove(int *keyPtr) { DLLElement *temp; void *tempitem = NULL; if(IsEmpty()) { keyPtr = NULL; }else { *keyPtr = first->key; if(yield_type == 1) currentThread->Yield(); //the 1th positon of yield ****(1) //the returned tempitem may not the item we just removed! //the item maybe incorrect tempitem = first->item; temp = first; first = first->next; if(first != NULL) { if(yield_type == 2) currentThread->Yield(); //the 2th positon of yield ****(2) //the dllist may lose its item first->prev = NULL; }else last = NULL; } delete temp;
return tempitem; } //---------------------------------------------------------------------- // DLList::SortedInsert // // Insert an "item" into a dllist, so that the dllist elements are sorted in increasing order by "sortKey". //---------------------------------------------------------------------- void DLList::SortedInsert(void *item, int sortKey) { DLLElement *element = new DLLElement(item, sortKey); DLLElement *ptr; // keep track if (IsEmpty()) { // if list is empty, put first = element; if(yield_type == 3) currentThread->Yield(); //the 3th positon of yield ****(3) //the thread may make a mess of the dllist last = element; } else if (sortKey < first->key) { // item goes on front of list element->next = first; first->prev = element; first = element; } else { // look for first elt in list bigger than item ptr = first; while((sortKey >= ptr->key)&&(ptr->next != NULL)) ptr = ptr->next; if (sortKey < ptr->key) { (ptr->prev)->next = element; element->prev = ptr->prev; element->next = ptr; if(yield_type == 4) currentThread->Yield(); //the 4th positon of yield ****(4) //the dllist may be broken by multi-threads ptr->prev = element; }else { ptr->next = element; element->prev = ptr; last = element; } } } c)dllist-driver.cc (~/nachos/nachos-3.4/code/threads/)
链表驱动函数 Insert,Remove void Insert(int N,DLList *dllist,int TdNo) //Insert N items into the dllist. { int rd; srand(time(0)); for(int i=0;iSortedInsert(NULL,rd); printf("Thread %dth have inserted the item (key=%d)\n",TdNo,rd); } } void Remove(int N,DLList *dllist,int TdNo) //Remove N items from the dllist. { int keyword; for(int i=0;iRemove(&keyword); printf("Thread %dth have removed the item (key=%d)\n",TdNo,keyword); } } d)线程测试 threadtest.cc (~/nachos/nachos-3.4/code/threads/) 其中我们设置了几个全局变量,testnum,threadnum,N,lb1_cor_type,dllist。 testnum:测试号,对应相应的测试函数 threadnum:线程数,通过命令行参数录入 N:用于驱动函数插入或者删除链表项的控制 lb1_cor_type:用于指示不同切换位置可能出现的错误种类,通过命令行参数修改 dllist:用于线程操作的公共链表 我们在 threadtest.cc 中添加了新的测试函数 ThreadTest2,在其中,我们创建了 threadnum 个线程,每个线程都执行相同的操作,插入 N 个项,之后删除 N 个项,在这 里通过调用 DLListThread 函数实现。同时在进行这些操作的时候打印出相应的提示信 息。 void DLListThread(int n) { } Insert(N,dllist,n); Remove(N,dllist,n); void ThreadTest2() { DEBUG('t', "Entering ThreadTest2"); dllist = new DLList(lb1_cor_type); for(int i = 1; i < threadnum; i++) { Thread *t = new Thread("forked thread"); t->Fork(DLListThread, i);
} DLListThread(threadnum); } e)main.cc (~/nachos/nachos-3.4/code/threads/) 在 main 函数中,我们需要做的并不多,只需要将相应的参数处理即可。 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 'M'://指示切换位置 lb1_cor_type = atoi(argv[1]); argCount++; break; default: testnum = 1; break; } } f)Makefile.common (~/nachos/nachos-3.4/code /) 在 THREAD_H 下添加:../threads/dllist.h\ 在 THREAD_C 下添加:../threads/dllist.cc\ ../threads/dllist-driver.cc\ 在 THREAD_H 下添加:dllist.o dllist-driver.o 4.编译执行 在~/nachos/nachos-3.4/code/threads/下执行:make depend,然后执行 make 进行编译。 等编译成功后,执行:./nachos [-q 1|2] [-T t] [-N n] [-M m],其中带有[ ]为可选参数,参数 与顺序无关。 -q:选择测试函数 -T:设置线程数 -N:设置驱动函数的控制参数 -M:选择切换位置(位置选择不同出项的错误可能不同) 五、运行结果和错误分析 1.正常运行结果
1)执行:./nachos –q 1 2)执行:./nachos –q 2 –T 1 –N 3 (只有一个线程的情况) 2.错误出现 1)执行:./nachos –q 2 –N 2 –T 2 –M 1 出现第一类错误:插入与移出的元素不一样,插入 88,19,而移出为 19,19。(颜色 标记处)
2)执行:./nachos –q 2 –N 2 –T 2 –M 2 出现第二类错误:链表失去了自己的元素,插入 91,16,而只能移出 16,另一元 素 91 丢失。(颜色标记处) 3)执行:./nachos –q 2 –N 2 –T 2 –M 3 出现第三类错误:链表在被多个线程访问时其中的元素被打乱,一个线程插入的元素可 能被其他移出。(颜色标记处)
4)执行:./nachos –q 2 –N 3 –T 3 –M 4 出现第四类错误:链表被彻底损坏。(颜色标记处)
分享到:
收藏