第一篇:4100225-操作系統(tǒng)課程設(shè)計
計算機與通信工程學(xué)院
計算機操作系統(tǒng)課程設(shè)計
學(xué) 號: 姓 名: 提交日期: 成 績:
4100225 李彤 2013-01-10
第一部分:基于互斥量mutexes的線程互斥
一、設(shè)計任務(wù)
在Linux環(huán)境下實現(xiàn),一個線程從終端接收用戶的輸入,另一個線程顯示該字符串并清空用于輸入的數(shù)組,用互斥量mutexes保證,在同一時刻只能有一個線程存取該字符串數(shù)組。
二、源代碼
1.Linux代碼
#include sem_s;int data; void write_data(int *a){ data=*a; printf(“write data1”); sem_post(&s);} void read_data(void){ sem_wait(&s); int product; product=data[0]*data[1]; printf(“輸出:%d*%d=%dn”,data);} int main(void){ sem_init(&s,0,0); int a=1; pthread_create(&t1,NULL,(void *)operate,NULL); pthread_create(&t2,NULL,(void *)operate,&a); pthread_join(t1,NULL); pthread_join(t2,NULL);} 2.Windows代碼 #include string a;int s=1; void write(){ if(s=1) s=s-1,cout<<“請輸入數(shù)據(jù):”,cin>>a,s=s+1;else cout< void read(){ if(s=1){ s=s-1; cout< s=s+1;} else cout<<“不能讀取數(shù)據(jù)?!? system(“pause”);} void main(){ int choose;cout<<“1.寫入數(shù)據(jù)”< cin>>choose; if(choose==3) cout<<“謝謝使用?!? write();else if(choose==2) read(); main();} 三、運行結(jié)果 第二部分:進程管理器 一、設(shè)計任務(wù) 在Linux或Window系統(tǒng)環(huán)境下,實現(xiàn)一個系統(tǒng)進程管理器,能夠顯示當前系統(tǒng)的活動進程信息(進程名、用戶、優(yōu)先級、內(nèi)存使用等),并能結(jié)束或創(chuàng)建特定進程??蓞⒖糤indow下“任務(wù)管理器”功能。 二、源代碼 #include node *neirong;struct jincheng *next;}; struct jincheng *neijin,*neizhi,*p,*q; //創(chuàng)建新進程 int creat(){ int i;if(shumu>20){ printf(“內(nèi)存已滿請先換出進程!n”); i=-1; return i;} else { if(neijin==NULL)//如果就緒隊列中沒有進程的話 { p=(jincheng*)malloc(sizeof(jincheng)); printf(“請輸入新進程的名字(數(shù)字):n”); scanf(“%d”,&p->pid); printf(“請輸入新進程的優(yōu)先級:(數(shù)字)n”); scanf(“%d”,&p->youxian); p->luntime=3.5; p->zhantime=3; p->neirong=(node*)malloc(sizeof(node)); p->neirong=NULL; p->zhuangtai='b';//新建進程的狀態(tài)設(shè)置為“就緒” p->next=NULL; neijin=p; shumu++; i=1; } else//如果就緒隊列不是空隊列 { p=neijin; while(p->next!=NULL) { p=p->next;//p一直指向就緒隊列的隊尾 } q=(jincheng*)malloc(sizeof(jincheng)); q->next=p->next; p->next=q;//在就緒隊列的隊尾加入新建的進程 printf(“請輸入新進程的名字(數(shù)字):n”); scanf(“%d”,&q->pid); printf(“請輸入新進程的優(yōu)先級:(數(shù)字)n”); scanf(“%d”,&q->youxian); q->luntime=3.5; q->zhantime=3; q->neirong=(node*)malloc(sizeof(node)); q->neirong=NULL; q->zhuangtai='b';//新建進程的狀態(tài)設(shè)置為就緒 shumu++; i=1; } } return i;} //換出進程 void huanchu(int a){ p=neijin;while(p->pid!=a&&p!=NULL){ q=p; p=p->next;} if(p==NULL){ printf(“該進程不在內(nèi)存里!n”); return;} if(p==neijin){ neijin=neijin->next;} else { q->next=p->next;//把目標進程從就緒隊列中移出來 } } //結(jié)束進程 void jieshu(){ neizhi->next=NULL;printf(“運行的進程已經(jīng)結(jié)束!n”);return;} //創(chuàng)建新進程后與正在運行進程比較優(yōu)先級并根據(jù)優(yōu)先級判斷誰該占用處理機 int bijiao(){ int i,j;p=neijin;while(p!=NULL){ q=p; p=p->next;//q指向進程的末尾,即新建的進程 } i=q->youxian;//i代表新進進程的優(yōu)先級 j=neizhi->next->youxian;//j代表正在執(zhí)行進程的優(yōu)先級 if(i>j)//如果新建的進程的優(yōu)先級高于正在執(zhí)行程序的優(yōu)先級 { p=neijin; if(p==q)//就緒隊列的進程中只有一個進程 { neijin=neizhi->next; p->neirong=(node*)malloc(sizeof(node)); p->neirong->a=9; p->neirong->ch='c'; neizhi->next=p;//把處理機交給優(yōu)先級高的新進程 return 1; } else { while(p->next!=q) { p=p->next; }//執(zhí)行完后p指針在q指針前面 p->next=neizhi->next;//將正在執(zhí)行的進程放置p的后面 q->neirong=(node*)malloc(sizeof(node)); q->neirong->a=9; q->neirong->ch='c'; neizhi->next=q;//將q放置在正在執(zhí)行列表中,把處理機交給優(yōu)先級高的進程 neizhi->next->next=NULL; return 1; } } else return-1;} //從活動就緒進程隊列中找到一個優(yōu)先級最高的進程并為它分配處理機 int zhixing(){ int i,j;p=neijin;if(neizhi->next!=NULL){ return-1;} i=neijin->youxian;p=neijin->next;while(p!=NULL){ j=p->youxian; if(i>=j) { p=p->next; } if(i { i=p->youxian; p=p->next; } } if(neijin->youxian==i){ neijin->neirong=(node*)malloc(sizeof(node)); neijin->neirong->a=9; neijin->neirong->ch='c'; neizhi->next=neijin; neijin=neijin->next; neizhi->next->next=NULL;} else { p=neijin; while(i!=p->youxian) { q=p; p=p->next; }// q是p前面的指針 p->neirong=(node*)malloc(sizeof(node)); p->zhuangtai='a'; p->neirong->a=9; p->neirong->ch='c'; neizhi->next=p;//將p放入執(zhí)行列表 q->next=p->next;//將優(yōu)先級高的節(jié)點舍去 } return 1;} //查看進程 void chakan(){ p=neizhi->next;printf(“該執(zhí)行進程的名字為:%dn”,p->pid);printf(“該執(zhí)行進程的的優(yōu)先級:%dn”,p->youxian);printf(“該執(zhí)行進程的輪轉(zhuǎn)時間為:%fn”,p->luntime);printf(“該執(zhí)行進程占用cpu的時間為:%fn”,p->zhantime);printf(“該執(zhí)行的進程內(nèi)容為:n”);printf(“%d ”,p->neirong->a);printf(“%c”,p->neirong->ch);printf(“n”);} //進程通信 void tongxin(int a){ q=neijin;while(q->pid!=a&&q!=NULL){ q=q->next;}//q為id為a的進程 if(q==NULL){ printf(“所輸入的進程不在內(nèi)存中!n”); return;} p=neizhi->next;//p為正在執(zhí)行的進程 q->neirong=(node*)malloc(sizeof(node));q->neirong->a=p->neirong->a;q->neirong->ch=p->neirong->ch;//將正在執(zhí)行的進程內(nèi)容復(fù)制給id為a的進程 printf(“通信成功!n”);return;} //主函數(shù) void main(){ int zhixing();//定義函數(shù) void jieshu();//定義函數(shù) void chakan();//定義函數(shù) void tongxin(int);//定義函數(shù) neizhi=(jincheng*)malloc(sizeof(jincheng));neizhi->next=NULL;neijin=(jincheng*)malloc(sizeof(jincheng)); neijin->next=NULL; neijin->pid=1;neijin->youxian=6;neijin->luntime=3.5;neijin->zhantime=3; neijin->neirong=(node*)malloc(sizeof(node));neijin->neirong=NULL;neijin->zhuangtai='b';shumu++;p=(jincheng*)malloc(sizeof(jincheng));p->next=neijin->next;neijin->next=p; p->pid=2;p->youxian=5;p->luntime=3.5;p->zhantime=3;p->neirong=(node*)malloc(sizeof(node));p->neirong=NULL;p->zhuangtai='b';shumu++; q=(jincheng*)malloc(sizeof(jincheng));q->next=p->next;p->next=q;q->pid=3;q->youxian=4;q->luntime=3.5;q->zhantime=3;q->neirong=(node*)malloc(sizeof(node));q->neirong=NULL;q->zhuangtai='b';shumu++;int i,n=1;int k,j,s;j=zhixing();int creat();while(n==1){ printf(“********************************************n”); printf(“* 進程演示系統(tǒng) *n”); printf(“********************************************n”); printf(“ 1.創(chuàng)建新的進程 2.查看運行進程 n”); printf(“ 3.換出某個進程 4.結(jié)束運行進程 n”); printf(“ 5.進程之間通信 6.退出系統(tǒng) n”); printf(“********************************************n”); printf(“請選擇(1~6)n”); scanf(“%d”,&i); switch(i) { case 1:k=creat(); if(k==1) printf(“進程創(chuàng)建成功!n”); if(neijin->next==NULL) { printf(“由于只有一個進程所以為它分配處理機.n”); neizhi->next=neijin; neijin->neirong=(node*)malloc(sizeof(node)); neijin->neirong->a=3; neijin->neirong->ch='c'; neijin=NULL; continue; } k=bijiao(); if(k==1) { printf(“由于新進程的優(yōu)先級高于正在執(zhí)行的進程所以正在執(zhí)行的n”); printf(“進程讓出處理機交給新進程,而它變?yōu)榛顒泳途w!n”); } if(k!=1) printf(“新進程的優(yōu)先級低于正在運行的進程所以它只有等待!n”); break; case 2: if(neizhi->next==NULL) { printf(“沒有進程處于執(zhí)行狀態(tài)!n”); continue; } chakan();break; case 3: if(neijin==NULL) { printf(“內(nèi)存中已經(jīng)沒有處于活動就緒的進程了請創(chuàng)建!n”); continue; } printf(“已有處于活動就緒進程的名字為:n”); p=neijin; printf(“(”); while(p!=NULL) { printf(“%d ”,p->pid); p=p->next; } printf(“)n”); printf(“請輸入要換出的處于活動就緒進程的名字n”); scanf(“%d”,&s); huanchu(s); if(neijin==NULL) printf(“內(nèi)存中已經(jīng)沒有活動就緒進程!n”); else { printf(“已有處于活動就緒進程的名字為:n”); p=neijin; printf(“(”); while(p!=NULL) { printf(“%d ”,p->pid); p=p->next; } printf(“)n”); } break; case 4: if(neizhi->next==NULL) { printf(“沒有處于執(zhí)行狀態(tài)的進程!n”); continue; } jieshu(); if(neijin==NULL) { printf(“已經(jīng)沒有處于活動就緒的進程請創(chuàng)建!n”); continue; } j=zhixing(); if(j==1) { printf(“已為一個動態(tài)就緒進程中優(yōu)先級最高的進程分配處理器!n”); } break; case 5: if(neijin==NULL) { printf(“內(nèi)存中已經(jīng)沒有處于活動就緒的進程了請創(chuàng)建!n”); continue; } if(neizhi->next==NULL) { printf(“沒有處于執(zhí)行狀態(tài)的進程!n”); continue; } printf(“請輸入要與正在運行的進程進行進程通訊的進程名字n”); scanf(“%d”,&s); tongxin(s); break; case 6:exit(0); default:n=0; } } } 三、運行結(jié)果 湖北民族學(xué)院信息工程學(xué)院11級計算機專業(yè)操作系統(tǒng)課程設(shè)計 (操作系統(tǒng)課程設(shè)計) 連續(xù)動態(tài)分區(qū)內(nèi)存 管理模擬實現(xiàn) 學(xué)生姓名: 韓 慧 學(xué)生學(xué)號: 031140312 班 級: 031140--3 0311401、02、03、04班制 二〇一三年十二月 湖北民族學(xué)院信息工程學(xué)院11級計算機專業(yè)操作系統(tǒng)課程設(shè)計 目錄 《操作系統(tǒng)》課程設(shè)計.......................................................1 引言......................................................................3 課程設(shè)計目的和內(nèi)容......................................................3 需求分析.........................................................................3 概要設(shè)計...................................................................3 開發(fā)環(huán)境........................................................................4 系統(tǒng)分析設(shè)計.....................................................................4 有關(guān)了解內(nèi)存管理的相關(guān)理論..................................................4 內(nèi)存管理概念........................................................................4 內(nèi)存管理的必要性..............................................................4 內(nèi)存的物理組織.............................................................4 什么是虛擬內(nèi)存.................................................................5 連續(xù)動態(tài)分區(qū)內(nèi)存管理方式...................................................5 單一連續(xù)分配(單個分區(qū))...................................................5 固定分區(qū)存儲管理...............................................................5 可變分區(qū)存儲管理(動態(tài)分區(qū))..............................................5 可重定位分區(qū)存儲管理........................................................5 問題描述和分析....................................................................6 程序流程圖........................................................................6 數(shù)據(jù)結(jié)構(gòu)體分析..................................................................8 主要程序代碼分析...............................................................9 分析并實現(xiàn)四種內(nèi)存分配算法.................................................11 最先適應(yīng)算.....................................................................11 下次適應(yīng)分配算法..........................................................13 最優(yōu)適應(yīng)算法...............................................................16 最壞適應(yīng)算法...............................................................18 回收內(nèi)存算法................................................................20 調(diào)試與操作說明.................................................................22 初始界面.......................................................................22 模擬內(nèi)存分配...............................................................23 已分配分區(qū)說明表面............................................................24 空閑區(qū)說明表界面.............................................................24 回收內(nèi)存界面.....................................................................25 重新申請內(nèi)存界面..........................................................26.總結(jié)與體會......................................................................28 湖北民族學(xué)院信息工程學(xué)院11級計算機專業(yè)操作系統(tǒng)課程設(shè)計 參考文獻.........................................................................28 引言 操作系統(tǒng)是最重要的系統(tǒng)軟件,同時也是最活躍的學(xué)科之一。我們通過操作系統(tǒng)可以理解計算機系統(tǒng)的資源如何組織,操作系統(tǒng)如何有效地管理這些系統(tǒng)資源,用戶如何通過操作系統(tǒng)與計算機系統(tǒng)打交道。 存儲器是計算機系統(tǒng)的重要組成部分,近年來,存儲器容量雖然一直在不斷擴大,但仍不能滿足現(xiàn)代軟件發(fā)展的需要,因此,存儲器仍然是一種寶貴而又緊俏的資源。如何對它加以有效的管理,不僅直接影響到存儲器的利用率,而且還對系統(tǒng)性能有重大影響。而動態(tài)分區(qū)分配屬于連續(xù)分配的一種方式,它至今仍在內(nèi)存分配方式中占有一席之地。 課程設(shè)計目的和內(nèi)容: 理解內(nèi)存管理的相關(guān)理論,掌握連續(xù)動態(tài)分區(qū)內(nèi)存管理的理論;通過對實際問題的編程實現(xiàn),獲得實際應(yīng)用和編程能力。 編寫程序?qū)崿F(xiàn)連續(xù)動態(tài)分區(qū)內(nèi)存管理方式,該程序管理一塊虛擬內(nèi)存,實現(xiàn)內(nèi)存分配和回收功能。分析并實現(xiàn)四種內(nèi)存分配算法,即最先適應(yīng)算法,下次最先適應(yīng)算法,最優(yōu)適應(yīng)算法,最壞適應(yīng)算法。內(nèi)存分配算法和回收算法的實現(xiàn)。 需求分析 動態(tài)分區(qū)分配是根據(jù)進程的實際需要,動態(tài)地為之分配內(nèi)存空間。在實現(xiàn)動態(tài)分區(qū)分配時,將涉及到分區(qū)分配中所用的數(shù)據(jù)結(jié)構(gòu)、分區(qū)分配算法和分區(qū)的分配和回收操作這樣三個問題。常用的數(shù)據(jù)結(jié)構(gòu)有動態(tài)分區(qū)表和動態(tài)分區(qū)鏈。在對數(shù)據(jù)結(jié)構(gòu)有一定掌握程度的情況下設(shè)計合理的數(shù)據(jù)結(jié)構(gòu)來描述存儲空間,實現(xiàn)分區(qū)存儲管理的內(nèi)存分配功能,應(yīng)該選擇最合適的適應(yīng)算法(首次適應(yīng)算法,最佳適應(yīng)算法,最后適應(yīng)算法,最壞適應(yīng)算法),在動態(tài)分區(qū)存儲管理方式中主要實現(xiàn)內(nèi)存分配和內(nèi)存回收算法,在這些存儲管理中間必然會有碎片的產(chǎn)生,當碎片產(chǎn)生時,進行碎片的拼接等相關(guān)的內(nèi)容 概要設(shè)計 本程序采用機構(gòu)化模塊化的設(shè)計方法,共分為四大模塊。⑴最先適應(yīng)算法實現(xiàn) 從空閑分區(qū)表的第一個表目起查找該表,把最先能夠滿足要求的空閑區(qū)分配給作業(yè),這種方法目的在于減少查找時間。為適應(yīng)這種算法,空閑分區(qū)表(空閑區(qū)鏈)中的空閑分區(qū)要按地址由低到高進行排序。該算法優(yōu)先使用低址部分空閑區(qū),在低址空間造成許多小的空閑區(qū),在高地址空間保留大的空閑區(qū)。⑵下次適應(yīng)分配算法實現(xiàn) 湖北民族學(xué)院信息工程學(xué)院11級計算機專業(yè)操作系統(tǒng)課程設(shè)計 該算法是最先適應(yīng)算法的變種。在分配內(nèi)存空間時,不再每次從表頭(鏈首)開始查找,而是從上次找到空閑區(qū)的下一個空閑開始查找,直到找到第一個能滿足要求的的空閑區(qū)為止,并從中劃出一塊與請求大小相等的內(nèi)存空間分配給作業(yè)。該算法能使內(nèi)存中的空閑區(qū)分布得較均勻。⑶最優(yōu)適應(yīng)算法實現(xiàn) 它從全部空閑區(qū)中找出能滿足作業(yè)要求的、且大小最小的空閑分區(qū),這種方法能使碎片盡量小。為適應(yīng)此算法,空閑分區(qū)表(空閑區(qū)鏈)中的空閑分區(qū)要按從小到大進行排序,自表頭開始查找到第一個滿足要求的自由分區(qū)分配。⑷最壞算法實現(xiàn) 最壞適應(yīng)分配算法要掃描整個空閑分區(qū)或鏈表,總是挑選一個最大的空閑分區(qū)分割給作業(yè)使用。該算法要求將所有的空閑分區(qū)按其容量從大到小的順序形成一空閑分區(qū)鏈,查找時只要看第一個分區(qū)能否滿足作業(yè)要求。 開發(fā)環(huán)境: win7 下 VC++6.0 系統(tǒng)分析設(shè)計: 相關(guān)算法原理,算法流程圖,涉及的數(shù)據(jù)結(jié)構(gòu)內(nèi)容都相應(yīng)包含在各章節(jié)中 有關(guān)了解內(nèi)存管理的相關(guān)理論 內(nèi)存管理概念: 內(nèi)存管理,是指軟件運行時對計算機內(nèi)存資源的分配和使用的技術(shù)。其最主要的目的是如何高效,快速的分配,并且在適當?shù)臅r候釋放和回收內(nèi)存資源。內(nèi)存不是預(yù)先劃分好的,而是在系統(tǒng)運行的過程中建立分區(qū).當作業(yè)裝入主存時,根據(jù)作業(yè)所需要的主存容量查看是否有足夠的主存空間,若有則按需要分割一個分區(qū)給該作業(yè);否則令該作業(yè)等待.分區(qū)長度不固定分區(qū)個數(shù)不固定。這種存儲管理的方法克服了固定分區(qū)嚴重浪費主存的問題,提高了主存資源的利用率。 內(nèi)存管理的必要性: 內(nèi)存管理對于編寫出高效率的 Windows 程序是非常重要的,這是因為Windows 是多任務(wù)系統(tǒng),它的內(nèi)存管理和單任務(wù)的 DOS 相比有很大的差異。DOS是單任務(wù)操作系統(tǒng),應(yīng)用程序分配到內(nèi)存后,如果它不主動釋放,系統(tǒng)是不會對它作任何改變的;但 Windows 卻不然,它在同一時刻可能有多個應(yīng)用程序共享內(nèi)存,有時為了使某個任務(wù)更好地執(zhí)行,Windows 系統(tǒng)可能會對其它任務(wù)分配的內(nèi)存進行移動,甚至刪除。因此,我們在 Windows 應(yīng)用程序中使用內(nèi)存時,要遵循Windows 內(nèi)存管理的一些約定,以盡量提高 Windows 內(nèi)存的利用率。湖北民族學(xué)院信息工程學(xué)院11級計算機專業(yè)操作系統(tǒng)課程設(shè)計 1.3 內(nèi)存的物理組織: 物理地址: 把內(nèi)存分成若干個大小相等的存儲單元,每個存儲單元占 8 位,稱作字節(jié)(byte)。每個單元給一個編號,這個編號稱為物理地址(內(nèi)存地址、絕對地址、實地址)。 二、物理地址空間: 物理地址的集合稱為物理地址空間(主存地址空間),它是一個一維空間。 什么是虛擬內(nèi)存: 虛擬內(nèi)存是內(nèi)存管理技術(shù)的一個極其實用的創(chuàng)新。它是一段程序(由操作系統(tǒng)調(diào)度),持續(xù)監(jiān)控著所有物理內(nèi)存中的代碼段、數(shù)據(jù)段,并保證他們在運行中的效率以及可靠性,對于每個用戶層(user-level)的進程分配一段虛擬內(nèi)存空間。當進程建立時,不需要在物理內(nèi)存件之間搬移數(shù)據(jù),數(shù)據(jù)儲存于磁盤內(nèi)的虛擬內(nèi)存空間,也不需要為該進程去配置主內(nèi)存空間,只有當該進程被被調(diào)用的時候才會被加載到主內(nèi)存。 連續(xù)動態(tài)分區(qū)內(nèi)存管理方式的實現(xiàn) 在早期的操作系統(tǒng)中,主存分配廣泛采用連續(xù)分配方式。連續(xù)分配方式,是指為一個用戶程序分配一個連續(xù)的內(nèi)存空間,該連續(xù)內(nèi)存空間指的的是物理內(nèi)存。下面介紹連續(xù)分配的四種方式。 單一連續(xù)分配(單個分區(qū)) 最簡單的存儲管理方式,用于多道程序設(shè)計技術(shù)之前。內(nèi)存分為系統(tǒng)區(qū)和用戶區(qū),系統(tǒng)區(qū)由操作系統(tǒng)使用。用戶區(qū)作為一個連續(xù)的分區(qū)分配給一個作業(yè)。分區(qū)存儲管理是滿足多道程序設(shè)計的最簡單的一種存儲管理方法,它允許多 4個用戶程序同時存在系統(tǒng)內(nèi)存中,即共享內(nèi)存空間。按分區(qū)劃分方式可分為固定分區(qū)和可變分區(qū)。 固定分區(qū)存儲管理 把內(nèi)存的用戶區(qū)預(yù)先劃分成多個分區(qū),每個分區(qū)大小可以相同,也可以不同。(分區(qū)的劃分由計算機的操作員或者由操作系統(tǒng)給出,并給出主存分配表)分區(qū)個數(shù)固定,分區(qū)的大小固定。一個分區(qū)中可裝入一個作業(yè),作業(yè)執(zhí)行過程中不會改變存放區(qū)域。早期的 IBM 的 OS/MFT(具有固定任務(wù)數(shù)的多道程序系統(tǒng))采用了這種固定分區(qū)的方法。 可變分區(qū)存儲管理(動態(tài)分區(qū)) 內(nèi)存不是預(yù)先劃分好的,而是在系統(tǒng)運行的過程中建立分區(qū).當作業(yè)裝入主存時,根據(jù)作業(yè)所需要的主存容量查看是否有足夠的主存空間,若有則按需要分割一個分區(qū)給該作業(yè);否則令該作業(yè)等待。分區(qū)長度不固定分區(qū)個數(shù)不固定。這種存儲管理的方法克服了固定分區(qū)嚴重浪費主存的問題,提高了主存資源的利用率。IBM操作系統(tǒng)OS/MVT采用可變分區(qū)存儲管理。湖北民族學(xué)院信息工程學(xué)院11級計算機專業(yè)操作系統(tǒng)課程設(shè)計 可重定位分區(qū)存儲管理 解決碎片問題的一種簡單方法是采用可重定位分區(qū)分配.。其中心思想是,把不同程序,且在內(nèi)存中地址不連續(xù)的想法讓他們連續(xù)。 例:內(nèi)存中現(xiàn)有 3 個空閑區(qū),現(xiàn)有一作業(yè)到達,要求獲得 30k 內(nèi)存空間,沒有分區(qū)滿足容量要求,若想把作業(yè)裝入,可將內(nèi)存中所有作業(yè)進行移動,這樣把原來分散的空閑區(qū)匯集成一個大的空閑區(qū)。將內(nèi)存中的作業(yè)進行移動使它們連接在一起把原來分散的多個小分區(qū)拼接成一個大的空閑區(qū).這個過程稱為”緊湊”或”移動”。需解決的問題:每次”緊湊”后程序或數(shù)據(jù)裝入的物理地址變化采用動態(tài)重定位。 問題描述和分析 系統(tǒng)應(yīng)利用某種分配算法,從空閑分區(qū)鏈表中找到所需大小的分區(qū),如果空閑分區(qū)大小大于請求分區(qū)大小,則從該分區(qū)中按改請求的大小劃分出一塊內(nèi)存空間大小劃分出一塊內(nèi)存空間分配出去,余下的部分仍留在空閑鏈表中。然后,將分配區(qū)的首址返回給調(diào)用者。 當進程運行完畢師范內(nèi)存時,系統(tǒng)根據(jù)回收區(qū)的首址,從空閑區(qū)中找到相應(yīng)的插入點,此時可能出現(xiàn)以下四種情況之一: ⑴該空閑區(qū)的上下兩相鄰分區(qū)都是空閑區(qū):將三個空閑區(qū)合并為一個空閑區(qū)。新空閑區(qū)的起始地址為上空閑區(qū)的起始地址,大小為三個空閑區(qū)之和??臻e區(qū)合并后,取消可用表或自由鏈中下空閑區(qū)的表目項或鏈指針,修改上空閑區(qū)的對應(yīng)項。 ⑵該空閑區(qū)的上相鄰區(qū)是空閑區(qū):將釋放區(qū)與上空閑區(qū)合并為一個空閑區(qū),其起始地址為上空閑區(qū)的起始地址,大小為上空閑區(qū)與釋放區(qū)之和。合并后,修改上空閑區(qū)對應(yīng)的可用表的表目項或自由鏈指針。 ⑶該空閑區(qū)的下相鄰區(qū)是空閑區(qū):將釋放區(qū)與下空閑區(qū)合并,并將釋放區(qū)的起始地址作為合并區(qū)的起始地址。合并區(qū)的長度為釋放區(qū)與下空閑區(qū)之和。同理,合并后修改可用表或自由鏈中相應(yīng)的表目項或鏈指針。 ⑷兩相鄰區(qū)都不是空閑區(qū):釋放區(qū)作為一個新空閑可用區(qū)插入可用表或自由鏈。 程序流程圖 內(nèi)存分配流程圖,如圖 湖北民族學(xué)院信息工程學(xué)院11級計算機專業(yè)操作系統(tǒng)課程設(shè)計 從頭開始查表檢索完否?NY返回分區(qū)大小>所需大小N繼續(xù)檢索下一個表項Y分區(qū)大小-所需大小<=不可再分割大小N從該分區(qū)中劃出所需大小的新分區(qū)Y將該分區(qū)從鏈中移出將該分區(qū)分配給請求者修改有關(guān)數(shù)據(jù)結(jié)構(gòu)返回 內(nèi)存回收流程圖,如圖 湖北民族學(xué)院信息工程學(xué)院11級計算機專業(yè)操作系統(tǒng)課程設(shè)計 開始判斷空閑區(qū)上下內(nèi)存情況上為空下為空上下都為空上下都不為空將上面的空閑區(qū)合并,并回收將下面的空閑區(qū)合并,并回收將上下的空閑區(qū)合并,并回收直接將其回收結(jié)束 數(shù)據(jù)結(jié)構(gòu)體分析 ⑴進程屬性結(jié)構(gòu)體 typedef struct readyque { char name[10];int size;}readyque,*readyqueue;⑵空閑鏈表結(jié)構(gòu)體 typedef struct idlyspace { int from;int size;idlyspace * next;}idlyspace,*idly;⑶已分配鏈表結(jié)構(gòu)體 typedef struct busyspace { int from;readyque r;湖北民族學(xué)院信息工程學(xué)院11級計算機專業(yè)操作系統(tǒng)課程設(shè)計 busyspace * next;}busyspace,*busy 主要程序代碼分析 ⑴主函數(shù)//代碼請?zhí)砑舆m當?shù)淖⑨?。int main(){ Is=(idly)malloc(sizeof(idlyspace));Is->from=0;Is->size=256;Is->next=NULL;Is2=Is;Bs=(busy)malloc(sizeof(busyspace));Bs->next=NULL;int t,t1;printf(“n.......................歡迎來到動態(tài)分區(qū)存儲管理系統(tǒng)..................nn”);printf(“...........................請選擇要執(zhí)行的算法:...........................n”);printf(“.........................1.最先適應(yīng)算法 ...............................n”);printf(“.........................2.下次適應(yīng)算法............................n”);printf(“..........................3.最優(yōu)適應(yīng)算法 ...............................n”);printf(“.........................4.最壞適應(yīng)算法................................n”);printf(“........................................................................n”);printf(“請輸入您的選擇:”);scanf(“%d”,&t);int i;while(i!=5){ printf(“........................................................................n”); printf(“.........................操作菜單如下:(請選擇).......................n”); printf(“..........................1.輸入進程分配空間...........................n”); printf(“.........................2.進程撤銷回收空間...........................n”); printf(“.........................3.輸出所有空閑分區(qū) ..........................n”); printf(“..........................4.輸出所有已分配分區(qū)..........................n”); printf(“..........................5.退 出..........................n”); printf(“........................................................................n”); scanf(“%d”,&i); switch(i) { case 1: switch(t) { case 1: t1=FF();湖北民族學(xué)院信息工程學(xué)院11級計算機專業(yè)操作系統(tǒng)課程設(shè)計 break; case 2: t1=NF(); break; case 3: t1=BF(); break; case 4: t1=WF(); break; default: printf(“選擇算法錯誤n”); return 1; } if(t1) printf(“分配空間成功n”); else printf(“分配空間失敗n”); break; case 2: t1=recover(); if(t1) printf(“回收成功n”); else printf(“回收失敗n”); break; case 3: Isprint(); break; case 4: Bsprint(); break; } } return 0;} 第三章 :分析并實現(xiàn)四種內(nèi)存分配算法 最先適應(yīng)算法 空閑區(qū)按地址從小到大的次序排列。 分配:當進程申請大小為 SIZE 的內(nèi)存時,系統(tǒng)順序查找空閑區(qū)表(鏈),直到找到容量滿足要求(≥SIZE)的空閑區(qū)為止。從該空閑區(qū)中劃出大小為 SIZE的分區(qū)分配給進程,余下的部分仍作為一個空閑區(qū),但要修改其首址和大小。湖北民族學(xué)院信息工程學(xué)院11級計算機專業(yè)操作系統(tǒng)課程設(shè)計 優(yōu)點:這種算法是盡可能地利用低地址部分的空閑區(qū),而盡量地保證高地址 6部分的大空閑區(qū),有利于大作業(yè)的裝入。 缺點:主存低地址和高地址分區(qū)利用不均衡。在低地址部分集中了許多非常小的空閑區(qū)碎片降低了主存的利用率。最先適應(yīng)算法 int FF(){ int t=0;readyque D;printf““請輸入進程名:””);scanf““%””,D.name); printf““輸入進程申請空間大小:””);scanf““%””,&D.size); idly l=Is;int mt=256;busy b=Bs;idly min=NULL;while(l) //尋找空閑表中大小滿足申請進程所需大小并且起址最小的空閑結(jié)點 { if(D.size<=l->size) { if(l->from { mt=l->from;min=l;t=1; } } l=l->next;} if(mt!=256) { busy j; j=(busy)malloc(sizeof(busyspace)); //如果找到則為進程分配空間 湖北民族學(xué)院信息工程學(xué)院11級計算機專業(yè)操作系統(tǒng)課程設(shè)計 j->from=min->from; for(int i=0;i<10;i++) { j->r.name[i]=D.name[i]; } j->r.size=D.size; while(b->next) { if(b->next->from b=b->next;else break; } j->next=b->next; b->next=j; min->from=min->from+D.size; min->size=min->size-D.size;} return t;} 下次適應(yīng)分配算法 最先適應(yīng)算法的變種。 總是從空閑區(qū)上次掃描結(jié)束處順序查找空閑區(qū)表(鏈),直到找到第一個滿足容量要求的空閑區(qū)為止,分割一部分給作業(yè),剩余部分仍作為空閑區(qū)。下次適應(yīng)分配算法 int NF(){ int t=0;readyque D;printf““請輸入進程名:””);scanf““%””,D.name); 湖北民族學(xué)院信息工程學(xué)院11級計算機專業(yè)操作系統(tǒng)課程設(shè)計 printf““輸入進程申請空間大小:””);scanf““%””,&D.size); int mt=256;idly l=Is2;idly min=NULL;busy b=Bs;while(l)//尋找空閑表中大小滿足申請進程所需大小并且起址最小的空閑結(jié)點 { if(D.size<=l->size) { if(l->from { mt=l->from;min=l;t=1; } } l=l->next;} if(mt!=256) { busy j; j=(busy)malloc(sizeof(busyspace)); j->from=min->from; for(int i=0;i<10;i++) { j->r.name[i]=D.name[i]; } j->r.size=D.size; while(b->next) { if(b->next->from b=b->next;else break; //如果找到則為進程分配空間 湖北民族學(xué)院信息工程學(xué)院11級計算機專業(yè)操作系統(tǒng)課程設(shè)計 } //將申請空間進程插入到已分配鏈表中 j->next=b->next; b->next=j; //修改相應(yīng)空閑節(jié)點的起址和大小 min->from=min->from+D.size; min->size=min->size-D.size; Is2=min->next; 結(jié)點 t=1; return t;} l=Is;//l指向空閑表的頭 while(l!=Is2) { if(D.size<=l->size) { if(l->from { mt=l->from;min=l;t=1; } } l=l->next;} if(mt!=256){ busy j; j=(busy)malloc(sizeof(busyspace)); j->from=min->from; for(int i=0;i<10;i++) { //ls2指向修改結(jié)點的下一個 //循環(huán)查找 湖北民族學(xué)院信息工程學(xué)院11級計算機專業(yè)操作系統(tǒng)課程設(shè)計 j->r.name[i]=D.name[i]; } j->r.size=D.size; while(b->next) { if(b->next->from b=b->next;else break; } j->next=b->next; b->next=j; min->from=min->from+D.size; min->size=min->size-D.size; Is2=min->next; t=1; return t;} return t;} 最優(yōu)適應(yīng)算法 空閑區(qū)按容量遞增的次序排列。 分配:當進程申請存儲空間,系統(tǒng)順序查找空閑區(qū)表(鏈),直到找到第一個滿足容量要求的空閑區(qū)為止。采用最優(yōu)適應(yīng)算法選中的空閑區(qū)是滿足容量要求的最小空閑區(qū)。優(yōu)點:選中的空閑區(qū)是滿足容量要求的最小空閑區(qū),而不致于毀掉較大的空閑區(qū)。 缺點:空閑區(qū)的大小一般與申請分區(qū)大小不相等,因此將其一分為二,留下來的空閑區(qū)一般情況下是很小的,以致無法使用。隨著時間的推移,系統(tǒng)中的小空閑區(qū)會越來越多,從而造成存儲空間的浪費。最優(yōu)適應(yīng)算法 int BF(){ int t=0;湖北民族學(xué)院信息工程學(xué)院11級計算機專業(yè)操作系統(tǒng)課程設(shè)計 readyque D;printf““請輸入進程名:””);scanf““%””,D.name); printf““輸入進程申請空間大小:””);scanf““%””,&D.size); idly l=Is;idly min=NULL;int mt=256;busy b=Bs;while(l)//在空閑鏈中尋找第一個大于所輸入的進程大小的空閑塊 { if(D.size<=l->size) { if(l->size { mt=l->size;min=l;t=1; } } l=l->next;} if(mt!=256) { busy j; j=(busy)malloc(sizeof(busyspace));空間 j->from=min->from; //申請分配用于存放進程的內(nèi)存 //找到第一個滿足要求的空閑塊 //將第一個滿足要求的空閑塊(min)的首地址賦給j for(int i=0;i<10;i++) { j->r.name[i]=D.name[i];16 湖北民族學(xué)院信息工程學(xué)院11級計算機專業(yè)操作系統(tǒng)課程設(shè)計 } j->r.size=D.size; while(b->next) //按從小到大的順序查找新進程在已分配區(qū)中的位置 { if(b->next->from b=b->next;else break; } j->next=b->next; b->next=j; min->from=min->from+D.size; min->size=min->size-D.size; } return t;} 最壞適應(yīng)算法 為了克服最佳適應(yīng)算法把空閑區(qū)切割得太小的缺點,人們提出了一種最壞適應(yīng)算法,即每次分配時,總是將最大的空閑區(qū)切去一部分分配給請求者,剩余的部分仍是一個較大的空閑區(qū)。避免了空閑區(qū)越分越小的問題。要求空閑區(qū)按容量遞減的順序排列。 分配:進程申請存儲區(qū)時,檢查空閑區(qū)表(鏈)的第一個空閑區(qū)的大小是否滿足要求,若不滿足則令進程等待;若滿足則從該空閑區(qū)中分配一部分存儲區(qū)給用戶,剩下的部分仍作為空閑區(qū)。最壞適應(yīng)算法 int WF(){ int t=0;readyque D;printf““請輸入進程名:””);scanf““%””,D.name); printf““輸入進程申請空間大小:””); //將所輸入的進程插入進程鏈 //改變該空閑塊的起始地址 //改變該空閑塊的剩余大小 湖北民族學(xué)院信息工程學(xué)院11級計算機專業(yè)操作系統(tǒng)課程設(shè)計 scanf““%””,&D.size); //輸入進程申請的空間大小 idly l=Is;//l指向空閑鏈表ls頭 idly min=NULL;int mt=0;busy b=Bs; //b指向已分配鏈表Bs頭 //找到空閑分區(qū)中大小滿足進程的請求且尺寸最大的結(jié)點 while(l){ if(D.size<=l->size)//判斷進程所申請的大小是否小于空閑區(qū)的各結(jié)點大小 { if(l->size>mt) { mt=l->size;min=l;//min指向空閑區(qū)中尺寸最大的結(jié)點 t=1; } } l=l->next;} if(mt!=0)點 { busy j; j=(busy)malloc(sizeof(busyspace)); j->from=min->from; for(int i=0;i<10;i++) { j->r.name[i]=D.name[i]; } j->r.size=D.size; //判斷是否找到了空閑區(qū)的滿足結(jié) //l指向空閑鏈表下一個結(jié)點 湖北民族學(xué)院信息工程學(xué)院11級計算機專業(yè)操作系統(tǒng)課程設(shè)計 while(b->next)置 //尋找插入到已分配鏈表中的位 { if(b->next->from b=b->next;else break; } //把此進程結(jié)點j插入到已分配鏈表中 j->next=b->next; b->next=j; //修改空閑鏈表的相應(yīng)結(jié)點的參數(shù) min->from=min->from+D.size; min->size=min->size-D.size;} return t;} 可變分區(qū)的回收 當某個進程釋放某存儲區(qū)時,系統(tǒng)首先檢查釋放區(qū)是否與系統(tǒng)中的空閑區(qū)相鄰若相鄰則把釋放區(qū)合并到相鄰的空閑區(qū)去,否則把釋放區(qū)作為一個空閑區(qū)插入到空閑表的適當位置。 釋放區(qū)與空閑區(qū)相鄰的四種情況。 (1)釋放區(qū)與前空閑區(qū)相鄰:把釋放區(qū)與前空閑區(qū)合并到一個空閑區(qū)。其首址仍為前空閑區(qū)首址,大小為釋放區(qū)大小與空閑區(qū)大小之和。 (2)釋放區(qū)與后空閑區(qū)相鄰:則把釋放區(qū)合并到后空閑區(qū),其首地址為釋放區(qū)首地址,大小為二者之和。 (3)釋放區(qū)與前后兩空閑區(qū)相鄰:這三個區(qū)合為一個空閑區(qū),首地址為前空閑區(qū)首址,大小為這三個空閑區(qū)之和,并取消后空閑區(qū)表目。 (4)釋放區(qū)不與任何空閑區(qū)相鄰:將釋放區(qū)作為一個空閑區(qū),將其大小和首址插入到空閑區(qū)表的適當位置。 湖北民族學(xué)院信息工程學(xué)院11級計算機專業(yè)操作系統(tǒng)課程設(shè)計 回收內(nèi)存算法 int recover(){ readyque D;printf““請輸入想要回收的進程名””); scanf““%””,D.name); busy b=Bs;idly l=Is;while(b->next)鏈表中 { bool yo=1; for(int i=0;i<10;i++) { if(b->next->r.name[i]==D.name[i])yo=yo*1; else yo=0; } //如果在已分配鏈表中則釋放該結(jié)點所占空間 if(yo) { int t=b->next->from; int ts=b->next->r.size; //查找輸入的進程名是否在已分配湖北民族學(xué)院信息工程學(xué)院11級計算機專業(yè)操作系統(tǒng)課程設(shè)計 while(l) { if(l->from>t+ts)不鄰接 { idly tl;tl=(idly)malloc(sizeof(idlyspace));tl->from=t;tl->size=ts;tl->next=l;Is=tl;break;} if(l->from==t+ts) l->from=t; l->size=l->size+ts; busy tb=b->next; b->next=b->next->next; free(tb); return 1;} if(l->from+l->size idly tl; tl=(idly)malloc(sizeof(idlyspace)); tl->from=t; tl->size=ts; tl->next=l->next; l->next=tl; break;} else if(l->from+l->size==t) //所回收進程與空閑結(jié)點上鄰接 { //所回收進程與空閑結(jié)點上下都不鄰接 //所回收進程與空閑結(jié)點下鄰接 { //所回收進程與空閑結(jié)點上下都 21 湖北民族學(xué)院信息工程學(xué)院11級計算機專業(yè)操作系統(tǒng)課程設(shè)計 l->size=l->size+ts; if(l->from+l->size==l->next->from)接 { l->size=l->size+l->next->size; idly tm=l->next; l->next=l->next->next; freI); } br l=l->next; } //從已分配鏈表中釋放所回收進程 busy tb=b->next; b->next=b->next->next; free(tb); return 1; } b=b->next;} printf(“沒找到這”進程n”);return 0;} //所回收進程與空閑結(jié)點上下都鄰調(diào)試與操作說明 初始界面 程序初始界面,有四個塊選擇,選擇要執(zhí)行的算法,調(diào)試以最壞算法為例,如圖 湖北民族學(xué)院信息工程學(xué)院11級計算機專業(yè)操作系統(tǒng)課程設(shè)計 選擇最壞適應(yīng)算法,如圖 模擬內(nèi)存分配 給進程a分配內(nèi)存20,如圖 湖北民族學(xué)院信息工程學(xué)院11級計算機專業(yè)操作系統(tǒng)課程設(shè)計 已分配分區(qū)說明表界面 同理,給進程b分配內(nèi)存30,給進程c分配內(nèi)存40,給進程d分配50,給進程e分配60,如圖 空閑分區(qū)說明表界面 湖北民族學(xué)院信息工程學(xué)院11級計算機專業(yè)操作系統(tǒng)課程設(shè)計 查看空閑分區(qū),如圖 回收內(nèi)存界面 回收進程b和d所占內(nèi)存,如圖 已分配分區(qū)說明表和空閑分區(qū)說明表 如圖 湖北民族學(xué)院信息工程學(xué)院11級計算機專業(yè)操作系統(tǒng)課程設(shè)計 重新申請內(nèi)存界面 再為新進程i分配內(nèi)存30,如圖 湖北民族學(xué)院信息工程學(xué)院11級計算機專業(yè)操作系統(tǒng)課程設(shè)計 根據(jù)最壞適應(yīng)算法結(jié)合圖所示可知,該算法將會從空閑分區(qū)表中選擇一塊最大的內(nèi)存空間分配給進程i,從圖也可看出該模擬算法實現(xiàn)了最壞適應(yīng)算法 湖北民族學(xué)院信息工程學(xué)院11級計算機專業(yè)操作系統(tǒng)課程設(shè)計 總結(jié)與體會 本次做的課題是動態(tài)分區(qū)分配算法實現(xiàn),此次課程設(shè)計成功實現(xiàn)了內(nèi)存分配和內(nèi)存回收,內(nèi)存分配中包含了四種算法,分別是首次適應(yīng)算法,循環(huán)首次適應(yīng)算法,最佳適應(yīng)算法和最壞適應(yīng)算法。經(jīng)編碼調(diào)試,表明該程序模塊是有效可行的。 通過這門課程的學(xué)習(xí)讓我充分了解了內(nèi)存管理的機制實現(xiàn),從而更深一步的的對計算機 有了很多了解,這對于以后我們的研究和學(xué)習(xí)計算機系統(tǒng)起到了很重要的作用。 對于本次論文制作,自己的編程能力有所提高,對操作系統(tǒng)內(nèi)存分配,存儲空間的回收都有全新的認識。 在這次操作系統(tǒng)課程設(shè)計中,我使用了c++編寫系統(tǒng)軟件,對os中可變分區(qū)存儲管理有了深刻的理解,但是過程中遇到了很多困難,一邊做一邊學(xué),對c++有了比較多的理解。 實驗中遇到很多問題,浪費了很多時間,總而言之是自己學(xué)習(xí)還不夠好,不扎實,希望在以后學(xué)習(xí)中加以改善,學(xué)到更多知識。 參考文獻 【1】 湯子瀛,哲鳳屏,湯小丹.計算機操作系統(tǒng).西安:西安電子科技大學(xué)出版社,2001.。湖北民族學(xué)院信息工程學(xué)院11級計算機專業(yè)操作系統(tǒng)課程設(shè)計 【2】 任愛華.操作系統(tǒng)實用教程.北京:清華大學(xué)出版社,2001。 長春理工大學(xué) 軟件學(xué)院 0813111班 27號 姓名:丁為勝 一. 概述 1、課程設(shè)計目的及任務(wù)課程設(shè)計地點及要求 每個學(xué)生一臺微機,需要安裝windows98或windows2000操作系統(tǒng),配備VC、VB、java或C編程語言,每個學(xué)生上機時間不少于24個小時。 操作系統(tǒng)是計算機專業(yè)的核心專業(yè)課,“操作系統(tǒng)課程設(shè)計”是理解和鞏固操作系統(tǒng)基本理論、原理和方法的重要的實踐環(huán)節(jié)。 操作系統(tǒng)課程主要講述的內(nèi)容是多道操作系統(tǒng)的原理與技術(shù),與其它計算機原理、編譯原理、匯編語言、計算機網(wǎng)絡(luò)、程序設(shè)計等專業(yè)課程關(guān)系十分密切。本課程設(shè)計的目的綜合應(yīng)用學(xué)生所學(xué)知識,建立系統(tǒng)和完整的計算機系統(tǒng)概念,理解和鞏固操作系統(tǒng)基本理論、原理和方法,掌握操作系統(tǒng)基本理論與管理方式。在算法基礎(chǔ)上,解決實際的管理功能的問題,提高學(xué)生實際應(yīng)用、編程的能力。 主要任務(wù)是實現(xiàn)操作系統(tǒng)和相關(guān)系統(tǒng)軟件的設(shè)計,其中涉及進程創(chuàng)建,同步,進程間的通信,存儲管理,文件系統(tǒng)等操作系統(tǒng)概念。 2.課程設(shè)計地點及要求 每個學(xué)生一臺微機,需要安裝windows98或windows2000操作系統(tǒng),配備VC、VB、java或C編程語言,每個學(xué)生上機時間不少于24個小時。 3.課程設(shè)計的內(nèi)容 設(shè)計二: 設(shè)計任務(wù): 掌握進程的管道通訊機制和信號量同步互斥機制。1. 進程的管道通訊 編制一個程序,程序中創(chuàng)建一個子進程。然后父子進程各自獨立運行,父進程不斷地在標準輸入設(shè)備上讀入小寫字母,寫入管道。子進程不斷地從管道中讀取字符,轉(zhuǎn)換為大寫字母后輸出到標準輸出設(shè)備上。當讀到x時,結(jié)束。 2. 信號量實現(xiàn)的同步互斥機制 編制一個程序,程序中創(chuàng)建5個子進程,代表五位哲學(xué)家,然后父進程結(jié)束。使用信號量機制解決哲學(xué)家進餐問題。當哲學(xué)家進餐時,屏幕輸出: [進程號] eating!當哲學(xué)家思考時,屏幕輸出: [進程號] thinging!相關(guān)的系統(tǒng)調(diào)用和函數(shù):pipe();write();read();semget();sepop();semctl();要求:查找并閱讀上述系統(tǒng)調(diào)用的相關(guān)資料,將上述相關(guān)的函數(shù)封裝為P()、V()操作,使用你封裝的P()、V()操作實現(xiàn)5位哲學(xué)家的同步和互斥。 二. 設(shè)計的基本概念和原理 1.進程的管道通訊 管道(Pipe)實際是用于進程間通信的一段共享內(nèi)存,創(chuàng)建管道的進程稱為管道服務(wù)器,連接到一個管道的進程為管道客戶機。命名管道(Named Pipes)是在管道服務(wù)器和一臺或多臺管道客戶機之間進行單向或雙向通信的一種命名的管道。一個命名管道的所有實例共享同一個管道名,但是每一個實例均擁有獨立的緩存與句柄,并且為客戶——服務(wù)通信提供有一個分離的管道。實例的使用保證了多個管道客戶能夠在同一時間使用同一個命名管道。 2.信號量實現(xiàn)的同步互斥機制 規(guī)定奇數(shù)號的哲學(xué)家先拿起他左邊的筷子,然后再去拿他右邊的筷子;而偶數(shù)號 的哲學(xué)家則相反.按此規(guī)定,將是1,2號哲學(xué)家競爭1號筷子,3,4號哲學(xué)家競爭3號筷子.即 五個哲學(xué)家都競爭奇數(shù)號筷子,獲得后,再去競爭偶數(shù)號筷子,最后總會有一個哲學(xué)家能獲 得兩支筷子而進餐。而申請不到的哲學(xué)家進入阻塞等待隊列,根FIFO原則,則先申請的哲 學(xué)家會較先可以吃飯,因此不會出現(xiàn)餓死的哲學(xué)家。 三. 總體設(shè)計 1.實現(xiàn)的方法和主要技術(shù)路線 1.無名管道 無名管道用于具有親緣關(guān)系的父子進程,子子進程之間的通訊。它的實現(xiàn)函數(shù)有 int pipe(int fd[2]); //fd[2] 為描述符數(shù)組,包含一個讀描述符與一個寫描述符,在使用管道通信時,關(guān)閉某些不需要的讀或?qū)懨枋龇⑵饐蜗虻淖x或?qū)懝艿?,然后用read 和write 像操作文件一樣去操作它即可。 如圖便是進程1 到進程2 的一個讀管道。 分別在父進程和父子進程里向管道寫數(shù)據(jù),然后在子進程和子子進程里讀數(shù)據(jù)。2.哲學(xué)家進餐偽碼: semaphore chopstick[5]={1,1,1,1,1};void philosopher(int i){ while(true){ think(); if(i%2 == 0)//偶數(shù)哲學(xué)家,先右后左。 { wait(chopstick[ i + 1 ] mod 5);wait(chopstick[ i]);eat(); signal(chopstick[ i + 1 ] mod 5);signal(chopstick[ i]);} Else //奇數(shù)哲學(xué)家,先左后右。 { wait(chopstick[ i]); wait(chopstick[ i + 1 ] mod 5);eat(); signal(chopstick[ i]); signal(chopstick[ i + 1 ] mod 5);} } 四. 詳細設(shè)計 進程的管道通信代碼: import java.io.IOException;import java.io.PipedReader; public class ReceiverThread1 extends Thread { PipedReader pipedReader; public ReceiverThread1(SenderThread1 sender)throws IOException { pipedReader=new PipedReader(sender.getPipedWriter()); } public void run() { char[] ch=new char[100];StringBuffer sb=null;String str=null;int i=0;try { while((i=pipedReader.read(ch))!=-1) { sb=new StringBuffer(); for(int j=0;j { sb.append(ch[j]); } str=sb.toString(); System.out.println(“子進程讀取的字符為:”+str.toUpperCase()); if(!str.endsWith(“x”)) { System.out.print(“父進程讀入字符為:”); }else if(str.endsWith(“x”)) { System.out.println(“結(jié)束無法再次輸入字符”); } } } catch(IOException e){ e.printStackTrace();}finally{ try { pipedReader.close(); } catch(IOException e){ e.printStackTrace(); } } } } import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PipedWriter; public class SenderThread1 extends Thread { PipedWriter pipedWriter; public SenderThread1(){ pipedWriter=new PipedWriter();} public PipedWriter getPipedWriter(){ return pipedWriter;} public void run() { BufferedReader ir=new BufferedReader(new InputStreamReader(System.in));char[] ch=new char[100];StringBuffer sb=null;String str=null;int i=0;System.out.print(“父進程讀入字符為:”);try { while((i=ir.read(ch))!=-1) { sb=new StringBuffer(); for(int j=0;j { if(ch[j]>='a' && ch[j]<='z') { sb.append(ch[j]); if(ch[j]=='x') { break; } } } str=sb.toString(); pipedWriter.write(str); if(str.startsWith(“x”)||str.endsWith(“x”)) { break; // this.stop(); } } } catch(IOException e){ e.printStackTrace();}finally{ try { ir.close(); pipedWriter.close(); } catch(IOException e){ e.printStackTrace(); } } } } public class ThreadComm1 { public static void main(String[] args)throws Exception{ SenderThread1 sender=new SenderThread1();ReceiverThread1 receiver=new ReceiverThread1(sender);sender.start();receiver.start();} } 哲學(xué)家進餐問題代碼: #include “stdafx.h” using namespace std;bool chop[100];//定義筷子 class ph { protected: bool * left,* right;//哲學(xué)家的左右手指向的筷子 int eattime;//哲學(xué)家的吃飯時間 public: bool check()//用于檢查哲學(xué)家左右手的筷子是不是被占用 { if(*left && *right) return true; else return false;} void eat(int ineattime)//哲學(xué)家開始進餐 { eattime=ineattime; *left=false; *right=false;} bool finish()//檢查哲學(xué)家是否完成進餐 { if(eattime>0)//沒完成的話剩余時間減少 { eattime--; if(eattime==0)//完成的話歸還筷子 { *left=true; *right=true; return true; } else return false; } else return false;} void init(int num,int max)//初始化哲學(xué)家,指定他們使用的筷子 { eattime=0; left=&chop[num]; if(num right=&chop[num+1]; else right=&chop[0];} };void main(){ system(“title 哲學(xué)家進餐問題”);int in,i,temp,time,j=1;queue for(int i=0;i<5;i++){ chop[i]=1; } for(int i=0;i<5;i++){ P[i].init(i,5);} cout<<“輸入哲學(xué)家進餐隊列:”< break;else if(in>5) { cout<<“一共只有”<<5<<“個人!”< } else { Q.push(in-1); } } cout<<“每個人吃飯時間:”< P[temp].eat(time); cout< if(temp+2>5) cout<<1< else cout< Q.push(temp);} for(i=0;i<5;i++) { if(P[i].finish()) cout< } //Q.push(-1); for(i=0;i { temp=Q.front(); Q.pop(); //if(temp!=-1) { cout< Q.push(temp); } //else { // Q.pop(); break; } } } for(int j=0;j第二篇:操作系統(tǒng)課程設(shè)計
第三篇:操作系統(tǒng)課程設(shè)計