歡迎來(lái)到裝配圖網(wǎng)! | 幫助中心 裝配圖網(wǎng)zhuangpeitu.com!
裝配圖網(wǎng)
ImageVerifierCode 換一換
首頁(yè) 裝配圖網(wǎng) > 資源分類 > DOC文檔下載  

中南大學(xué) 操作系統(tǒng)實(shí)驗(yàn)報(bào)告課程設(shè)計(jì)報(bào)告

  • 資源ID:30235322       資源大?。?span id="jddqplu" class="font-tahoma">522.50KB        全文頁(yè)數(shù):48頁(yè)
  • 資源格式: DOC        下載積分:15積分
快捷下載 游客一鍵下載
會(huì)員登錄下載
微信登錄下載
三方登錄下載: 微信開(kāi)放平臺(tái)登錄 支付寶登錄   QQ登錄   微博登錄  
二維碼
微信掃一掃登錄
下載資源需要15積分
郵箱/手機(jī):
溫馨提示:
用戶名和密碼都是您填寫(xiě)的郵箱或者手機(jī)號(hào),方便查詢和重復(fù)下載(系統(tǒng)自動(dòng)生成)
支付方式: 支付寶    微信支付   
驗(yàn)證碼:   換一換

 
賬號(hào):
密碼:
驗(yàn)證碼:   換一換
  忘記密碼?
    
友情提示
2、PDF文件下載后,可能會(huì)被瀏覽器默認(rèn)打開(kāi),此種情況可以點(diǎn)擊瀏覽器菜單,保存網(wǎng)頁(yè)到桌面,就可以正常下載了。
3、本站不支持迅雷下載,請(qǐng)使用電腦自帶的IE瀏覽器,或者360瀏覽器、谷歌瀏覽器下載即可。
4、本站資源下載后的文檔和圖紙-無(wú)水印,預(yù)覽文檔經(jīng)過(guò)壓縮,下載后原文更清晰。
5、試題試卷類文檔,如果標(biāo)題沒(méi)有明確說(shuō)明有答案則都視為沒(méi)有答案,請(qǐng)知曉。

中南大學(xué) 操作系統(tǒng)實(shí)驗(yàn)報(bào)告課程設(shè)計(jì)報(bào)告

操作系統(tǒng)實(shí)驗(yàn)報(bào)告界面設(shè)計(jì)l 菜單菜單包括菜單欄,菜單,菜單項(xiàng),一個(gè)菜單欄可以包括N個(gè)菜單,一個(gè)菜單可以包括菜單項(xiàng)。C語(yǔ)言設(shè)計(jì)菜單的思想是用雙向鏈表,先保存繪圖區(qū)的內(nèi)容,再在上面畫(huà)菜單。l 菜單結(jié)構(gòu)圖菜單欄菜單1菜單2菜單n.尾指針頭指針當(dāng)前指向菜單菜單項(xiàng)1菜單項(xiàng)2。菜單項(xiàng)n頭指針其他菜單項(xiàng)結(jié)構(gòu)類似結(jié)尾指針l 數(shù)據(jù)結(jié)構(gòu)1. 菜單欄:typedef struct menubar_sint number,x,y,barheight,baritemwidth;/*number用來(lái)記錄菜單項(xiàng)的數(shù)目,x,y用來(lái)記錄菜單欄在屏幕上的位置,barheight用來(lái)控制菜單欄的高度,baritemwidth用來(lái)控制每項(xiàng)菜單的寬度*/struct menu_s *mhead; /*指向第一個(gè)菜單*/struct menu_s *mtail; /*指向最后一個(gè)菜單*/struct menu_s *mpoint; /*當(dāng)用戶按下左右箭頭時(shí)用來(lái)記錄指向那個(gè)菜單,初始指向mhead*/void (* docommand)(); /*菜單時(shí)間的處理函數(shù)*/MenuBar;2. 菜單:typedef struct menu_sint number; /*菜單是菜單欄中的第幾項(xiàng)*/int subwidth; /*菜單項(xiàng)的寬度*/int subcount; /*菜單項(xiàng)的數(shù)目*/char *content; /*菜單顯示的字符串/struct menu_s *next; /*指向下一個(gè)菜單,如果是結(jié)尾菜單,則為NULL*/struct menu_s *before; /*指向前一個(gè)菜單,如果是頭菜單,則為NULL*/struct submenu_s *sub; /*指向當(dāng)前激活的菜單項(xiàng)*/struct submenu_s *head; /*指向第一個(gè)菜單項(xiàng)*/struct submenu_s *tail; /*指向最后一個(gè)菜單項(xiàng)*/Menu;3. 菜單項(xiàng):typedef struct submenu_sint number; /*菜單項(xiàng)是菜單中的第幾項(xiàng)*/int isactive; /*是否激活*/char *content; /*顯示的字符串*/struct submenu_s *next; /*指向下一個(gè)菜單項(xiàng)*/struct submenu_s *before; /*指向前一個(gè)菜單項(xiàng)*/submenu;l 函數(shù)實(shí)現(xiàn)1. 菜單構(gòu)造函數(shù)/*該函數(shù)的功能主要是根據(jù)指定的menutitle字符串,往菜單欄中添加一項(xiàng)菜單*/void addmenu(char *menutitle)if(Mb=NULL)/*如果Mb(全局MenuBar類型的變量)為NULL,說(shuō)明沒(méi)有初始化菜單欄,要初始化*/if(Mb=(MenuBar *)malloc(sizeof(MenuBar)=NULL)doerror("System error");Mb->number=0; /*菜單欄中菜單數(shù)目為0*/Mb->mpoint=Mb->mhead=Mb->mtail=NULL;Mb->x=0;Mb->y=0; /*位置于屏幕上(0,0)*/Mb->barheight=18; /*菜單欄高度為18*/Mb->baritemwidth=100; /*每項(xiàng)菜單的寬度為100*/Mb->docommand=docommand; /*設(shè)置事件處理函數(shù)為docommand()*/if(Mb->mtail=NULL) /*如果Mb->mtail為NULL,說(shuō)明要先構(gòu)造Mb->mhead*/if(Mb->mhead=(Menu *)malloc(sizeof(Menu)=NULL)doerror("System error");Mb->mhead->before=NULL;Mb->mtail=Mb->mhead;else if(Mb->mtail->next=(Menu *)malloc(sizeof(Menu)=NULL)doerror("System error");Mb->mtail->next->before=Mb->mtail;Mb->mtail=Mb->mtail->next;Mb->mtail->number=Mb->number; /*當(dāng)前添加進(jìn)去的菜單位置,下面有Mb->number的自加*/Mb->mtail->subwidth=0; /*菜單項(xiàng)的寬度為0*/Mb->mtail->subcount=0; /*菜單項(xiàng)數(shù)目為0/Mb->mtail->content=menutitle; /*把菜單的字符串指針指向menutitle*/Mb->mtail->next=NULL;Mb->mtail->sub=Mb->mtail->head=Mb->mtail->tail=NULL; /*把菜單項(xiàng)全部置NULL*/Mb->number+;/*菜單欄中number加1,表示加進(jìn)去了一個(gè)菜單*/ 2. 菜單項(xiàng)構(gòu)造函數(shù)/*該函數(shù)的功能是根據(jù)menu指定的字符串,往該菜單中添加以itemtitle為字符串的菜單項(xiàng)比如additem(“File”,”O(jiān)pen”)則執(zhí)行向File菜單中添加一項(xiàng)itemtitle菜單項(xiàng)*/void additem(char *menu,char *itemtitle) Mb->mpoint=Mb->mhead; /*先把指針指向菜單頭,這里借用Mb中的mpoint為了不用額外的變量*/ while(Mb->mpoint!=NULL) if(stricmp(Mb->mpoint->content,menu)=0) /*遍歷menu鏈表,如果找到一項(xiàng)和menu指定字符串相等的,則記錄下來(lái),跳出,*/ break; Mb->mpoint=Mb->mpoint->next; if(Mb->mpoint->tail=NULL) /*如果tail為空,則說(shuō)明沒(méi)有構(gòu)造頭節(jié)點(diǎn)head*/ if(Mb->mpoint->head=(submenu *)malloc(sizeof(submenu)=NULL) doerror("System error"); Mb->mpoint->head->before=NULL; Mb->mpoint->sub=Mb->mpoint->tail=Mb->mpoint->head; else if(Mb->mpoint->tail->next=(submenu *)malloc(sizeof(submenu)=NULL) doerror("System error"); Mb->mpoint->tail->next->before=Mb->mpoint->tail; Mb->mpoint->tail=Mb->mpoint->tail->next; if(strlen(itemtitle)>Mb->mpoint->subwidth) Mb->mpoint->subwidth=strlen(itemtitle); /*該語(yǔ)句主要計(jì)算一下剛加進(jìn)來(lái)的菜單項(xiàng)的字符數(shù),如果比菜單的寬度還要大,則把該寬度賦值給subwidth,主要是為了畫(huà)菜單是寬度足夠*/ Mb->mpoint->subcount+;/*菜單項(xiàng)數(shù)目加一*/ Mb->mpoint->tail->number=Mb->mpoint->subcount; Mb->mpoint->tail->isactive=0; Mb->mpoint->tail->content=itemtitle; Mb->mpoint->tail->next=NULL; 3. 繪畫(huà)菜單欄void drawmenu() Mb->mpoint=Mb->mhead; rectangle(0,0,getmaxx()-1,Mb->y+Mb->barheight);/*畫(huà)一個(gè)方框*/ while(Mb->mpoint!=NULL)outtextxy(Mb->mpoint->number*Mb->baritemwidth+Mb->x+5,Mb->y+6,Mb->mpoint->content); /*在菜單欄中逐項(xiàng)畫(huà)出菜單的內(nèi)容*/Mb->mpoint=Mb->mpoint->next;4. 繪畫(huà)當(dāng)前激活的菜單void drawsubmenu()submenu *temp;int x; /*x記錄當(dāng)前畫(huà)菜單的x位置*/x=Mb->mpoint->number*Mb->baritemwidth+Mb->x;temp=Mb->mpoint->head;copyimage(x,Mb->barheight+2,x+Mb->mpoint->subwidth*8+5,(Mb->mpoint->subcount+1)*Mb->barheight+3); /*保存繪畫(huà)區(qū)的內(nèi)容,copyimage為自寫(xiě)的函數(shù)*/setfillstyle(1,getbkcolor();bar(x,Mb->barheight+2,x+Mb->mpoint->subwidth*8+5,(Mb->mpoint->subcount+1)*Mb->barheight+3); /*用背景色把繪畫(huà)區(qū)覆蓋一下*/rectangle(x,Mb->barheight+2,x+Mb->mpoint->subwidth*8+5,(Mb->mpoint->subcount+1)*Mb->barheight+3); /*畫(huà)一個(gè)方框*/while(temp!=NULL)if(temp->isactive) /*如果是當(dāng)前激活的菜單,則畫(huà)一個(gè)紅色方框背景*/setfillstyle(1,RED);bar(x+2,temp->number*Mb->barheight+4,x+Mb->mpoint->subwidth*8+3,(temp->number+1)*Mb->barheight-1);outtextxy(x+5,temp->number*Mb->barheight+5,temp->content);temp=temp->next;4. 進(jìn)入菜單/*根據(jù)menu指定的字符串,說(shuō)明用戶從哪項(xiàng)菜單進(jìn)入菜單,如gotomenucur(”File”)說(shuō)明用戶激活了“File”菜單*/void gotomenucur(char *menu)Mb->mpoint=Mb->mhead;while(Mb->mpoint->next!=NULL)if(stricmp(Mb->mpoint->content,menu)=0)break;Mb->mpoint=Mb->mpoint->next;Mb->mpoint->sub=Mb->mpoint->head;Mb->mpoint->sub->isactive=1;drawsubmenu();5. 菜單按鍵處理void menukey()int key;while(1)key=get_key();switch(key)case KEY_LEFT: /*說(shuō)明用戶按下了向左按鍵,Mb->mpoint應(yīng)該向前移一項(xiàng)*/Mb->mpoint->sub->isactive=0;backimage(Mb->mpoint->number*Mb->baritemwidth+Mb->x,Mb->barheight+2);if(Mb->mpoint->before!=NULL) /*如果當(dāng)前已經(jīng)是mhead了,應(yīng)該指向mtail*/Mb->mpoint=Mb->mpoint->before;elseMb->mpoint=Mb->mtail;Mb->mpoint->sub=Mb->mpoint->head;Mb->mpoint->sub->isactive=1;drawsubmenu();/*重畫(huà)菜單,跳出*/break;case KEY_RIGHT: /*說(shuō)明用戶按下了向右鍵,解釋同KEY_LEFT*/Mb->mpoint->sub->isactive=0;backimage(Mb->mpoint->number*Mb->baritemwidth+Mb->x,Mb->barheight+2);if(Mb->mpoint->next!=NULL)Mb->mpoint=Mb->mpoint->next;elseMb->mpoint=Mb->mhead;Mb->mpoint->sub=Mb->mpoint->head;Mb->mpoint->sub->isactive=1;drawsubmenu();break;case KEY_UP: /*說(shuō)明用戶按下了向上鍵,應(yīng)把當(dāng)前激活的菜單項(xiàng)向上移一項(xiàng)*/Mb->mpoint->sub->isactive=0;backimage(Mb->mpoint->number*Mb->baritemwidth+Mb->x,Mb->barheight+2);if(Mb->mpoint->sub->before!=NULL)Mb->mpoint->sub=Mb->mpoint->sub->before;elseMb->mpoint->sub=Mb->mpoint->tail;Mb->mpoint->sub->isactive=1;drawsubmenu();break;case KEY_DOWN: /*說(shuō)明用戶按下了向下鍵,當(dāng)前菜單項(xiàng)應(yīng)向下移一項(xiàng)*/Mb->mpoint->sub->isactive=0;backimage(Mb->mpoint->number*Mb->baritemwidth+Mb->x,Mb->barheight+2);if(Mb->mpoint->sub->next!=NULL)Mb->mpoint->sub=Mb->mpoint->sub->next;elseMb->mpoint->sub=Mb->mpoint->head;Mb->mpoint->sub->isactive=1;drawsubmenu();break;case ENTER: /*說(shuō)明用戶按下了回車鍵,調(diào)用Mb->docommand()*/Mb->mpoint->sub->isactive=0;backimage(Mb->mpoint->number*Mb->baritemwidth+Mb->x,Mb->barheight+2);Mb->docommand();return;case ESC: /*說(shuō)明用戶按下了退出鍵,把拷貝的屏幕區(qū)域放回,不作任何處理*/Mb->mpoint->sub->isactive=0;backimage(Mb->mpoint->number*Mb->baritemwidth+Mb->x,Mb->barheight+2);return;游標(biāo)與滾屏l 思想在屏幕上顯示的是兩個(gè)隊(duì)列,一個(gè)是等待隊(duì)列,一個(gè)是就緒隊(duì)列。設(shè)置了一個(gè)游標(biāo),可以用上下鍵移動(dòng)指向每個(gè)進(jìn)程,然后對(duì)指向進(jìn)程進(jìn)行各種操作,包括掛起,解掛,刪除。我設(shè)置的屏幕上最多只能顯示12個(gè)進(jìn)程,就緒最多6個(gè),等待最多6個(gè),那么當(dāng)進(jìn)程多于此數(shù)時(shí),在用戶按上下鍵時(shí),應(yīng)該有滾屏功能。滾屏的思想如下:假設(shè)有就緒隊(duì)列里有N1個(gè)進(jìn)程,每個(gè)進(jìn)程編號(hào)1,2,3.N1-1,N1。等待隊(duì)列中有N2個(gè)進(jìn)程,每個(gè)進(jìn)程編號(hào)1,2,3N2-1,N2。假設(shè)當(dāng)前游標(biāo)指向的進(jìn)程編號(hào)小于6,則繪畫(huà)1到6個(gè)進(jìn)程(如果進(jìn)程數(shù)小于6則畫(huà)出所有進(jìn)程),如果當(dāng)前游標(biāo)指向的進(jìn)程編號(hào)為N(N>6),則繪畫(huà)N6到N個(gè),這樣就實(shí)現(xiàn)了滾屏。當(dāng)當(dāng)前游標(biāo)位置位于就緒隊(duì)列結(jié)尾,則當(dāng)用戶按下向下按鍵時(shí),應(yīng)該將游標(biāo)移動(dòng)到等待隊(duì)列的第一個(gè);當(dāng)當(dāng)前游標(biāo)位置位于就緒隊(duì)列第一個(gè),則當(dāng)用戶按下向上按鍵時(shí),應(yīng)該移動(dòng)到等待隊(duì)列最后一個(gè);同理,當(dāng)當(dāng)前游標(biāo)位于等待隊(duì)列隊(duì)尾對(duì)首時(shí),應(yīng)移動(dòng)就緒隊(duì)列隊(duì)首隊(duì)尾。l 函數(shù)實(shí)現(xiàn)因?yàn)槲野训却?duì)列和就緒隊(duì)列放在同一個(gè)鏈表里,所以要實(shí)現(xiàn)上面的功能可能有點(diǎn)problem,但多用幾個(gè)函數(shù)就能實(shí)現(xiàn)。1. /*這個(gè)函數(shù)用來(lái)給每個(gè)進(jìn)程編號(hào)*/void updateprocess()int i=1,j=1;process *temp;temp=phead;while(temp)if(temp->isrun) /*給就緒隊(duì)列中的進(jìn)程編號(hào)*/temp->pos=i+;else /*給等待隊(duì)列中的進(jìn)程編號(hào)*/temp->pos=j+;temp=temp->next;2. /*這個(gè)函數(shù)用來(lái)得到列表中就緒隊(duì)列中的第一個(gè)*/process *getfirstrun() process *temp; if(!phead) return NULL; temp=phead; while(temp!=NULL) if(temp->isrun) /*找到第一個(gè),就跳出循環(huán)*/ break; temp=temp->next; return temp->isrun?temp:NULL; /*如果找到就返回,否則就返回NULL,因?yàn)榭赡艽嬖谖ㄒ灰粋€(gè)等待隊(duì)列中的*/ 3. /*該函數(shù)用來(lái)獲取列表中就緒隊(duì)列中的最后一個(gè)*/ process *gettailrun() process *temp; if(!ptail) /*如果列表為空,則返回NULL*/ return NULL; temp=ptail; /*從列表尾部開(kāi)始找*/ while(temp!=NULL) if(temp->isrun) /*如果找到,就跳出循環(huán)*/ break; temp=temp->before; return temp->isrun?temp:NULL; /*判斷找到的是不是就緒隊(duì)列中的如果不是就返回NULL,因?yàn)榭赡艽嬖谥挥幸粋€(gè)等待隊(duì)列中的*/ 4. /*這個(gè)函數(shù)用來(lái)找相對(duì)于p的下一個(gè)就緒隊(duì)列中的進(jìn)程*/ process *getnextrun(process *p) process *temp; if(!p) return NULL; temp=p->next; while(temp!=NULL) if(temp->isrun) /*如果找到,就跳出循環(huán)*/ break; temp=temp->next; return temp; 5. /*這個(gè)函數(shù)用來(lái)找相對(duì)于p的前一個(gè)就緒隊(duì)列中的進(jìn)程*/ process *getbeforerun(process *p) process *temp; if(!p) return NULL; temp=p->before; while(temp!=NULL) if(temp->isrun) break; temp=temp->before; return temp; 6. /*這個(gè)函數(shù)用來(lái)找等待隊(duì)列中的第一個(gè),一下三個(gè)函數(shù)原理跟就緒隊(duì)列中的操作函數(shù)一樣,只是把查找的條件改成!temp->isrun*/ process *getfirstready() process *temp; if(!phead) return NULL; temp=phead; while(temp!=NULL) if(!temp->isrun) break; temp=temp->next; return temp->isrun?NULL:temp; 7. process *gettailready() process *temp; if(!ptail) return NULL; temp=ptail; while(temp!=NULL) if(!temp->isrun) break; temp=temp->before; return temp->isrun?NULL:temp; 8. process *getnextready(process *p) process *temp; if(!p) return NULL; temp=p->next; while(temp!=NULL) if(!temp->isrun) break; temp=temp->next; return temp; 9. process *getbeforeready(process *p) process *temp; if(!p) return NULL; temp=p->before; while(temp!=NULL) if(!temp->isrun) break; temp=temp->before; return temp; 10. /*這個(gè)函數(shù)用來(lái)得到下一個(gè)游標(biāo)的位置*/void getnext() process *temp; if(phead=ptail)/*如果鏈表中只有一個(gè)進(jìn)程,則什么也不處理,返回*/ ppoint=phead; return; if(ppoint=gettailrun()/*如果當(dāng)前游標(biāo)位置是就緒隊(duì)列中的最后一個(gè)*/ temp=getfirstready();/*則指向第一個(gè)等待隊(duì)列*/ ppoint=temp?temp:getfirstrun(); else if(ppoint=gettailready()/*如果當(dāng)前游標(biāo)位置是等待隊(duì)列中的最后一個(gè)*/ temp=getfirstrun();/*則指向就緒隊(duì)列中的第一個(gè)*/ ppoint=temp?temp:getfirstready(); else if(ppoint->isrun) /*如果當(dāng)前隊(duì)列在就緒隊(duì)列中移動(dòng)*/ ppoint=getnextrun(ppoint); /*移向就緒隊(duì)列中的下一個(gè)*/ else ppoint=getnextready(ppoint); /*移向等待隊(duì)列中的下一個(gè)*/ 11. /*這個(gè)函數(shù)用來(lái)得到上一個(gè)游標(biāo)的位置,基本的解釋同getnext()差不多*/ void getbefore() process *temp;if(phead=ptail) ppoint=phead;return; if(ppoint=getfirstrun() temp=gettailready(); ppoint=temp?temp:gettailrun(); else if(ppoint=getfirstready() temp=gettailrun(); ppoint=temp?temp:gettailready(); else if(ppoint->isrun) ppoint=getbeforerun(ppoint); else ppoint=getbeforeready(ppoint); 12. /*按鍵處理函數(shù)*/void key_U_D(int key)switch(key)case KEY_DOWN:if(!phead) ppoint=NULL;else getnext();break;/*如果按下的是向下鍵*/case KEY_UP:if(!ptail) ppoint=NULL;else getbefore();break; /*如果按下的是向上鍵*/if(ppoint) /*drawl_r(int,int)這個(gè)函數(shù)根據(jù)傳遞進(jìn)來(lái)的兩個(gè)參數(shù)指明應(yīng)該畫(huà)的起始編號(hào)*/if(ppoint->pos>6)if(ppoint->isrun)drawl_r(ppoint->pos-6,0);else drawl_r(0,ppoint->pos-6);else drawl_r(0,0);else drawl_r(0,0);獲取用戶按鍵C語(yǔ)言庫(kù)函數(shù)提供的getch(),或bioskey()在處理字符和菜單輸入時(shí)有點(diǎn)麻煩,改寫(xiě)了一個(gè)函數(shù)int get_key() union REGS rg; rg.h.ah=0; int86(0x16,&rg,&rg); if(rg.h.al=0)/*說(shuō)明按下了修飾鍵,把這個(gè)值左移8位*/return rg.h.ah<<8; return rg.h.al; /*直接返回按下的鍵值,實(shí)際上是ASCII*/舉例:當(dāng)用戶按下ALTF時(shí),返回的是8448,而按下F時(shí),返回的是F的ASCII圖形屏幕下獲取用戶的輸入因?yàn)檫@次課程設(shè)計(jì)只需獲得用戶輸入的整數(shù),所以處理也比較簡(jiǎn)單。long getinput(char *mess)/*輸入框提示的信息*/char desc50,number10,*endptr,*image;int i=0,key,width,x=200,y=300,size,color;width=strlen(mess)+10; /*計(jì)算窗口的寬度,按字符數(shù)來(lái)算,其中輸入的數(shù)字長(zhǎng)度最大為10*/size=imagesize(x,y,x+width*6,y+50); /*把窗口內(nèi)的屏幕保存下來(lái)*/if(image=(char *)malloc(size)=NULL)doerror("System error");getimage(x,y,x+width*6,y+50,image);setfillstyle(1,getbkcolor();bar(x,y,x+width*6,y+50);rectangle(x,y,x+width*6,y+50); /*用背景色覆蓋一下,相當(dāng)于清屏*/strcpy(desc,mess);outtextxy(x+10,y+20,mess);while(key=get_key()!=ENTER) /*如果沒(méi)有按下回車,則不退出*/if(key=ESC) /*如果按下ESC,則把拷貝的屏幕放回去,返回1*/putimage(x,y,image,0);free(image);return -1;if(key>=48&&key<=57|key=8) /*如果按下的是數(shù)字鍵或者是退格鍵*/if(key=8) /*如果是退格鍵,就用背景色把原來(lái)的字符畫(huà)一遍,相當(dāng)于覆蓋,然后去掉結(jié)尾一個(gè),用前景色畫(huà)字符,就相當(dāng)于刪掉一個(gè)字符(實(shí)際上也刪掉了)*/color=getcolor();setcolor(getbkcolor();outtextxy(x+10,y+20,strcat(desc,number);setcolor(color);number-i=0; /*這句相當(dāng)于刪掉一個(gè)字符*/else if(i<10)numberi+=key; /*把字符附加到末尾*/numberi=0;descstrlen(mess)=0;outtextxy(x+10,y+20,strcat(desc,number);putimage(x,y,image,0);free(image);return strtol(number,&endptr,10); /*把輸入的字符轉(zhuǎn)換為數(shù)字返回*/程序執(zhí)行流程首先說(shuō)明一下handle()函數(shù)的功能:void handler()int time,i,j,pos;/*time用來(lái)記錄上次執(zhí)行handle到這次執(zhí)行handle的時(shí)間間隔,i,j用來(lái)控制循環(huán),pos用來(lái)記錄光標(biāo)(用來(lái)指向每個(gè)進(jìn)程的一個(gè)小方塊)的位置*/if(ppoint!=NULL)if(ppoint->pos>6) /*因?yàn)槊總€(gè)隊(duì)列最多只能顯示6個(gè)隊(duì)列,所以當(dāng)當(dāng)前光標(biāo)指向的進(jìn)程的pos>6時(shí),pos一定是底部pos=6;else pos=ppoint->pos;bar(1-ppoint->isrun)*450,(pos-1)*50+80,(1-ppoint->isrun)*450+15,(pos-1)*50+85);/*畫(huà)一個(gè)游標(biāo)if(stop) /*stop是全局變量(為這是一個(gè)模擬程序,所以當(dāng)用戶想暫?;蛘呤裁吹模梢詴和#┕鹲top是true,則什么事都不做return;i=getnum(1); /*獲取就緒隊(duì)列中的進(jìn)程總數(shù)*/j=getnum(0); /*獲取等待隊(duì)列中的進(jìn)程總數(shù)*/if(i+j)<=0) /*如果兩個(gè)隊(duì)列為空*/stop=1;fresh();/*刷新一下屏幕*/return;if(i<maxrun&&j>0&&canrun) /*如果就緒隊(duì)列中的進(jìn)程數(shù)小于maxrun(maxrun為就緒隊(duì)列中的最大數(shù)目)且等待隊(duì)列不為空,且有足夠的內(nèi)存(maxrun為true時(shí)表示有足夠內(nèi)存)*/getfromeready();/*從等待隊(duì)列中選取一個(gè)優(yōu)先級(jí)最高,時(shí)間最少的*/coverfront();/*把游標(biāo)重畫(huà)一遍(這里放這個(gè)函數(shù)好像有點(diǎn)多余)*/gettime(&t2);time=(t2.ti_hour-t1.ti_hour)*60*60*100+(t2.ti_min-t1.ti_min)*60*100+(t2.ti_sec-t1.ti_sec)*100+t2.ti_hund-t1.ti_hund; /*計(jì)算兩次執(zhí)行handle的時(shí)間差,其實(shí)可以用gettime()這個(gè)庫(kù)函數(shù),但當(dāng)時(shí)沒(méi)發(fā)現(xiàn)。*/runtime-=time; /*runtime是時(shí)間片大小,是個(gè)全局變量*/drawsector();/*畫(huà)屏幕中間的時(shí)間片轉(zhuǎn)盤(pán)*/if(runtime<=0) /*如果當(dāng)前時(shí)間片用完了*/updatepri();/*更新一下進(jìn)程優(yōu)先權(quán),防止餓死*/drawl_r(0,0); /*重畫(huà)進(jìn)程列表*/Find_H_P();/*從就緒隊(duì)列中找優(yōu)先級(jí)最高的,時(shí)間最少的*/runtime=roundtime; /*roundtime是用來(lái)供用戶設(shè)定時(shí)間片大小的,把runtime的大小設(shè)為roundtime*/else drawcur(time); /*畫(huà)運(yùn)行進(jìn)程,這實(shí)際是個(gè)動(dòng)畫(huà)。*/t1=t2; /*更新t1的值,作為下次時(shí)間計(jì)算的標(biāo)準(zhǔn)*/setfillstyle(1,RED); /*重新設(shè)定填充模式,因?yàn)閐rawcru(time)函數(shù)中可能改變了填充模式*/Handle函數(shù)流程圖:判斷stop等隊(duì)列中的進(jìn)程總數(shù)小于maxrun且等待隊(duì)列中有進(jìn)程且有足夠內(nèi)存,從等待隊(duì)列中選取一個(gè)優(yōu)先級(jí)最高,時(shí)間最少的進(jìn)程進(jìn)就緒隊(duì)列從運(yùn)行隊(duì)列中減去所運(yùn)行了的時(shí)間,并用進(jìn)度條在屏幕上顯示出來(lái)False是否因?yàn)槌绦蛑杏玫搅瞬藛?,所以程序要保證執(zhí)行handle(),同時(shí)又不能耽誤用戶的輸入對(duì)菜單的操作,有兩種方法。方法一:利用DOS的時(shí)鐘中斷 int 21HAH=0x1C每秒產(chǎn)生18.2次中斷。在main函數(shù)中添加oldhandler = getvect(INTR);setvect(INTR, handler);其中INTR為宏定義define INTR 0x1c程序的流程圖:等待用戶按鍵捕獲按鍵,進(jìn)行相應(yīng)處理處理結(jié)束產(chǎn)生時(shí)鐘中斷,調(diào)用handle函數(shù)產(chǎn)生中斷方法二:用kbhit()檢測(cè)是否有有按鍵按下,如果有,則調(diào)用相應(yīng)的按鍵處理函數(shù),如果沒(méi)有則執(zhí)行handle函數(shù),然后調(diào)用delay函數(shù)延遲下一個(gè)循環(huán)。程序流程圖:是否有鍵盤(pán)按下捕獲按鍵進(jìn)行相應(yīng)處理處理結(jié)束執(zhí)行handle函數(shù)本次循環(huán)延世沒(méi)有有算法描述:進(jìn)程調(diào)度算法:如果stop為false,說(shuō)明用戶開(kāi)始程序模擬,檢查等待隊(duì)列中的進(jìn)程總數(shù)是否為maxrun(為系統(tǒng)運(yùn)行的負(fù)載),如果小于,則檢查等待隊(duì)列中是否有進(jìn)程,如果有,則再檢查是否有足夠內(nèi)存,如果都滿足,則從等待隊(duì)列中選取優(yōu)先級(jí)最高,時(shí)間最少的進(jìn)程運(yùn)行。當(dāng)一個(gè)時(shí)間片運(yùn)行完時(shí),則加大就緒隊(duì)列中相對(duì)低優(yōu)先級(jí)的優(yōu)先級(jí)數(shù),然后再選取下一個(gè)優(yōu)先級(jí)最高,時(shí)間最少的運(yùn)行。這樣可以防止低優(yōu)先級(jí)進(jìn)程的餓死。內(nèi)存分配算法:在選進(jìn)程進(jìn)入就緒隊(duì)列前,先看看當(dāng)前內(nèi)存分配算法是最佳適應(yīng)還是最先適應(yīng),看內(nèi)存中是否存在一塊足夠的內(nèi)存,如果足夠,則從內(nèi)存中劃去這一塊,如果這一塊相同大,則要?jiǎng)h除該鏈表節(jié)點(diǎn)。內(nèi)存回收算法:當(dāng)一個(gè)進(jìn)程運(yùn)行結(jié)束時(shí),要回收內(nèi)存,先記錄下該內(nèi)存塊的起始和終止地址,遍歷內(nèi)存鏈表,看該塊內(nèi)存的相鄰兩塊是不是也是空閑的,這時(shí)候可能會(huì)出現(xiàn)三種情況:情況一:相鄰兩塊只有一塊是空閑的,則直接合并進(jìn)去;情況二:相鄰兩塊都是空閑的,則要把這三塊合并成一塊,并刪除一個(gè)節(jié)點(diǎn);情況三:相鄰兩塊都不空閑,則直接創(chuàng)建一個(gè)內(nèi)存節(jié)點(diǎn),放入隊(duì)尾。最佳適應(yīng)算法:遍歷空閑內(nèi)存塊鏈表,找出大于所需內(nèi)存大小且是最小的一塊。最先適應(yīng)算法:從兩表頭開(kāi)始,只要找到一塊大于所需大小的就停止。PCB數(shù)據(jù)結(jié)構(gòu)typedef struct process_tint pid;/*進(jìn)程的pid*/int isrun; /*進(jìn)程是否在就緒隊(duì)列中,因?yàn)樗袪顟B(tài)的進(jìn)程都在一個(gè)隊(duì)列中,所以必須有這些標(biāo)識(shí)符變量來(lái)識(shí)別,實(shí)際操作系統(tǒng)中不是這樣的*/int ishalt; /*進(jìn)程是否被掛起*/int pos; /*進(jìn)程在屏幕中的位置,從1開(kāi)始按等待和就緒遞增*/int priority; /*進(jìn)程的優(yōu)先級(jí)*/int time_total; /*所需時(shí)間總數(shù)*/int time_left; /*還剩下的時(shí)間*/long startaddr; /*內(nèi)存的起始地址*/long size; /*內(nèi)存的大小*/void (*fun)(); /*函數(shù)入口*/struct process_t *next; /*指向下一個(gè)pcb*/struct process_t *before; /*指向上一個(gè)pcb*/process;內(nèi)存空閑塊數(shù)據(jù)結(jié)構(gòu)typedef struct memory_tlong startaddr;/*內(nèi)存的起始地址*/long size;/*空閑內(nèi)存的大小*/struct memory_t *next; /*指向下一個(gè)空閑內(nèi)存塊*/struct memory_t *before; /*指向上一個(gè)空閑內(nèi)存塊*/memory;屏幕畫(huà)圖菜單畫(huà)法:先計(jì)算當(dāng)前所畫(huà)菜單的大小,在內(nèi)存開(kāi)辟一個(gè)區(qū)域保存所畫(huà)區(qū)域內(nèi)容,然后從菜單頭節(jié)點(diǎn)開(kāi)始畫(huà)一直畫(huà)到鏈表末尾,如果用戶取消了或者按下了回車只要把保存的內(nèi)容放回原來(lái)的地方。進(jìn)程在屏幕上的畫(huà)法:由于鏈表只有一個(gè),而有就緒,等待,運(yùn)行三個(gè)隊(duì)列,其實(shí)運(yùn)行中只有一個(gè)進(jìn)程,只要在用一個(gè)process指針指向當(dāng)前運(yùn)行進(jìn)程就可以了。那么怎么把同一個(gè)鏈表中的進(jìn)程分別畫(huà)在屏幕兩邊的就緒和等待隊(duì)列中呢?(1-process->isrun)*screenweidth,這樣,如果它是就緒隊(duì)列中的(它的isrun是1),它就在屏幕的左邊,如果它是等待隊(duì)列中的(它的isrun是0),它就在屏幕的右邊。關(guān)于集成圖形驅(qū)動(dòng)做成exe文件在tc里頭,生成的exe文件如果是文本模式的,則可以運(yùn)行,而如果是圖形模式的,生成的exe老是提示你沒(méi)有初始化圖形驅(qū)動(dòng),可以把圖形驅(qū)動(dòng)集成到graphic里頭,方法如下:注冊(cè)圖形驅(qū)動(dòng):bgiobj EGAVGA 回車得到EGAVGA.OBJTLIB LIBGRAPHICS.LIB+EGAVGA.OBJ回車即可在程序中用registerbgidriver(EGAVGA_driver);其它對(duì)應(yīng)的如下CAG.BGI CGA_driverEGA.VGA.BGI EGAVGA_driverHERC.BGIHERC_driverATT.BGIATT_driverPC3270.BGIPC3270_driverIBM8514.BGIIBM8514_driver注冊(cè)字體:bgiobj trip|litt|sans|goth分別對(duì)應(yīng)字體trip.chr|litt.chr|sans.chr|goth.chrtlib libgraphics.lib+litt.obj字型驅(qū)動(dòng)registerbgifont()litt.chrtlib得到的字符名入"samll_font"源程序:#include <stdio.h>#include <stdlib.h>#include <dos.h>#include <conio.h>#include <graphics.h>#include <math.h>#include <string.h>/*包含一些必要的頭文件*/#define INTR 0X1C/*定義時(shí)鐘中斷號(hào)*/#define ENTER 13/*定義回車鍵*/#define KEY_UP 18432/*定義向上鍵的整數(shù)值*/#define KEY_DOWN 20480/*定義向下鍵的整數(shù)值*/#define KEY_LEFT 19200/*定義向左鍵的整數(shù)值*/#define KEY_RIGHT 19712/*定義向右鍵的整數(shù)值*/#define ALT_F 8448/*定義按下altf返回的整數(shù)值*/#define ALT_S 7936/*定義按下alts返回的整數(shù)值*/#define ALT_O 6144/*定義alto返回的整數(shù)值*/#define ALT_H 8960/*定義alth返回的整數(shù)值*/#define ESC 27/*定義esc返回的整數(shù)值,以上這些鍵值都是有g(shù)et_key()函數(shù)獲得*/typedef struct menubar_sint number,x,y,barheight,baritemwidth;struct menu_s *mhead;struct menu_s *mtail;struct menu_s *mpoint;void (* docommand)();MenuBar; /*定義一個(gè)菜單欄數(shù)據(jù)結(jié)構(gòu),在上面已經(jīng)解釋過(guò)*/typedef struct menu_sint number;int subwidth;int subcount;char *content;struct menu_s *next;struct menu_s *before;struct submenu_s *sub;struct submenu_s *head;struct submenu_s *tail;Menu; /*定義一個(gè)菜單結(jié)構(gòu)體,具體在上面已經(jīng)解釋過(guò)*/typedef struct submenu_sint number;int isactive;char *content;struct submenu_s *next;struct submenu_s *before;submenu; /*定義一個(gè)菜單項(xiàng),具體已在上面解釋過(guò)*/typedef struct process_tint pid;int isrun;int ishalt;int pos;int priority;int time_total;int time_left;long startaddr;long size;void (*fun)();struct process_t *next;struct process_t *before;process; /*定義一個(gè)pcb,在上面已經(jīng)解釋過(guò)*/typedef struct memory_tlong startaddr;long size;struct memory_t *next;struct memory_t *before;memory; /*定義一個(gè)空閑內(nèi)存塊結(jié)構(gòu),在上面已經(jīng)解釋過(guò)*/void docommand();void drawprocess(process *,int,int,int,int);void readfile();void writefile();void drawl_r(int,int);void addprocess();long getinput(char *);void savefile();void fresh();int findm_f_f(process *p);int findm_b_f(process *p);long getfreesize();void acceptm_f_f(process *p);void drawmembar();void creatememory(long,long);void rancreatep(long num);void randomcreate();void setmemsize();/*一些函數(shù)聲明,一下開(kāi)始定義全局變量*/MenuBar *Mb; /*一個(gè)菜單欄*/void *buff; /*用來(lái)保存畫(huà)菜單時(shí)預(yù)先保存的區(qū)域*/process *phead,*ptail,*prunning,*ppoint; /*用來(lái)保存進(jìn)程隊(duì)列的頭,尾,正在運(yùn)行,和當(dāng)前游標(biāo)指向的一個(gè)進(jìn)程*/struct time t1,t2; /*定義兩個(gè)time結(jié)構(gòu)體類型,用來(lái)記錄在兩次handle函數(shù)執(zhí)行之間的時(shí)間差*/memory *mhead,*mtail; /*空閑內(nèi)存塊的頭尾指針*/int roundtime=500,runtime=500,maxrun=5,stop=1,canrun=1,memway=1; /*roundtime用來(lái)保存時(shí)間片大小,runtime用來(lái)保存當(dāng)前時(shí)間片大小,maxrun用來(lái)保存系統(tǒng)所能運(yùn)行的最大進(jìn)程數(shù),stop用來(lái)控制是否停止模擬,canrun用來(lái)記錄系統(tǒng)是否有足夠內(nèi)存,memway用來(lái)記錄當(dāng)前內(nèi)存的適應(yīng)方式(最佳適應(yīng)還是最先適應(yīng))*/long memorysize=35460L; /*用來(lái)定義內(nèi)存大小*/int get_key() union REGS rg; rg.h.ah=0; int86(0x16,&rg,&rg); if(rg.h.al=0)return rg.h.ah<<8; return rg.h.al;/*這個(gè)函數(shù)用來(lái)獲取按鍵值,在上面已經(jīng)解釋過(guò)*/void doerror(char *s)int color;setfillstyle(1,getbkcolor();bar(200,200,300,300);rectangle(300,300,400,400);outtextxy(320,340,s);getch();closegraph();exit(1);/*如果系統(tǒng)內(nèi)存不足或者文件打不開(kāi),給出提示信息,并結(jié)束程序(目前也只能這樣做)*/void addmenu(char *menutitle) /*添加一個(gè)菜單*/if(Mb=NULL) /*如果Mb為NULL,說(shuō)明菜單欄還沒(méi)有初始化,接下去執(zhí)行一些初始化工作*/if(Mb=(MenuBar *)malloc(sizeof(MenuBar)=NULL)doerror("System error");/*分配一塊內(nèi)存區(qū)域*/Mb->number=0;Mb->mpoint=Mb->mhead=Mb->mtail=NULL;Mb->x=0;Mb->y=0;Mb->barheight=18;Mb->baritemwidth=100;Mb->docommand=docommand; /*初始化Mb中的一些變量,具體的變量含義已在上面解釋過(guò)*/if(Mb->mtail=NULL) /*如果當(dāng)

注意事項(xiàng)

本文(中南大學(xué) 操作系統(tǒng)實(shí)驗(yàn)報(bào)告課程設(shè)計(jì)報(bào)告)為本站會(huì)員(仙***)主動(dòng)上傳,裝配圖網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)上載內(nèi)容本身不做任何修改或編輯。 若此文所含內(nèi)容侵犯了您的版權(quán)或隱私,請(qǐng)立即通知裝配圖網(wǎng)(點(diǎn)擊聯(lián)系客服),我們立即給予刪除!

溫馨提示:如果因?yàn)榫W(wǎng)速或其他原因下載失敗請(qǐng)重新下載,重復(fù)下載不扣分。




關(guān)于我們 - 網(wǎng)站聲明 - 網(wǎng)站地圖 - 資源地圖 - 友情鏈接 - 網(wǎng)站客服 - 聯(lián)系我們

copyright@ 2023-2025  zhuangpeitu.com 裝配圖網(wǎng)版權(quán)所有   聯(lián)系電話:18123376007

備案號(hào):ICP2024067431號(hào)-1 川公網(wǎng)安備51140202000466號(hào)


本站為文檔C2C交易模式,即用戶上傳的文檔直接被用戶下載,本站只是中間服務(wù)平臺(tái),本站所有文檔下載所得的收益歸上傳人(含作者)所有。裝配圖網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)上載內(nèi)容本身不做任何修改或編輯。若文檔所含內(nèi)容侵犯了您的版權(quán)或隱私,請(qǐng)立即通知裝配圖網(wǎng),我們立即給予刪除!