第一篇:操作系統(tǒng)課程設(shè)計文件管理
#include “stdio.h” #include “string.h” #include “malloc.h”
#include “stdlib.h”
#define MAX 1000 struct file/*普通文件的結(jié)構(gòu)體*/ { //int type;//0無作用,當(dāng)做一個空節(jié)點存在;1為記錄型文件;2為執(zhí)行文件
//前兩個變量為文件的權(quán)限設(shè)置,1為允許操作,0為不允許操作
int write;//可寫
int read;//可讀
int length;//文件的長度
char ch[MAX];};typedef struct file File;
typedef struct ffile/*定義文件類型的結(jié)構(gòu)體*/ { int type;//1為文件夾; 2為文件;
char name[20];//文件(夾)名字
int open;//文件打開標(biāo)志,0為關(guān),1為開
File iffile;//如果為文件時有的信息
struct ffile *parent;//指向上一級文件的指針
struct ffile *brother;//指向同級兄弟文件(夾)的指針
struct ffile *child;//指向下一級文件(夾)的指針 }Ffile;typedef Ffile *FFile;
/*typedef struct Open/*記錄打開文件的結(jié)構(gòu)體 { char name[20];//記錄打開文件(夾)的名字
FFile* add;//記錄打開文件上一級文件地址的指針 }Open;*/
//全局變量
FFile user1;//用戶1 FFile user2;//用戶2 FFile copyf;//記錄被復(fù)制文件(夾)的上一級文件地址 //Open openf[20];//記錄打開文件的隊列
FFile init(void)/*初始化,創(chuàng)建根結(jié)點*/ { FFile c;c=(Ffile*)malloc(sizeof(Ffile));
c->type=2;c->open=0;//c->iffile.type=2;c->iffile.write=1;c->iffile.read=1;c->iffile.length=0;strcpy(c->name,“file1”);c->parent=NULL;c->child=NULL;c->brother=NULL;strcpy(c->iffile.ch,“NULL”);return(c);}
/*void initopen(){ int a,b;a=20;for(b=1;b<=a;b++){
openf[b].add=NULL;} }*/
//傳遞要顯示文件的parent的地址
void show(FFile user)/*顯示當(dāng)前界面存在的文件*/ { user=user->child;if(user==NULL){
printf(“該文件內(nèi)沒有任何文件(夾)。n”);return;} printf(“n”);for(;user!=NULL;){ printf(“<%s”,user->name);if(user->type==2){
/*if(user->iffile.type==1)
printf(“/記錄型文件/”);
else
printf(“/執(zhí)行文件/”);*/
printf(“/%dk”,user->iffile.length);} else {
printf(“/文件夾”);
}
printf(“>n”);
user=user->brother;} }
void creatf(FFile user)/*創(chuàng)建文件 || 文件夾*/ { FFile parent;char ch[20];//FFile user0;//parent=(Ffile*)malloc(sizeof(Ffile));parent=user;printf(“輸入要創(chuàng)建文件(夾)的名字:n”);
scanf(“%s”,ch);if(user->child==NULL){
user->child=(Ffile*)malloc(sizeof(Ffile));
user=user->child;}else {
user=user->child;
for(;;)
{
if(user->type==0)//開端的空結(jié)點,用新結(jié)點覆蓋
break;
if(!strcmp(user->name,ch))
{
printf(“錯誤:該文件名已經(jīng)存在,文件(夾)創(chuàng)建失??!n”);
return;
}
if(user->brother==NULL)
{
user->brother=(Ffile*)malloc(sizeof(Ffile));
user=user->brother;
break;
}
user=user->brother;
}
} }
//設(shè)置新文件(夾)的信息 strcpy(user->name,ch);printf(“選擇創(chuàng)建對象:1文件夾; 2文件;n”);scanf(“%d”,&user->type);user->open=0;if(user->type==2)//添加文件信息 {
//printf(“選擇文件類型:1記錄型文件;2執(zhí)行文件;n”);//scanf(“%d”,&user->iffile.type);printf(“能否對文件進(jìn)行讀:0禁止;1允許;n”);scanf(“%d”,&user->iffile.read);printf(“能否對文件進(jìn)行寫:0禁止;1允許;n”);scanf(“%d”,&user->iffile.write);//printf(“設(shè)置文件大小(單位:K):n”);//scanf(“%d”,&user->iffile.length);user->iffile.length=0;strcpy(user->iffile.ch,“NULL”);} user->brother=NULL;user->child=NULL;user->parent=parent;printf(“文件創(chuàng)建成功!n”);void deletechildtree(FFile user)/*刪除子樹--結(jié)合deletefile();使用*/ { if(user->brother!=NULL)//從下到上,從右到左刪除
{
deletechildtree(user->brother);} if(user->child!=NULL){
deletechildtree(user->child);} if(user!=NULL){
free(user);} }
void deletefile(FFile user,char ch[20])/*刪除文件 || 文件夾*/ { FFile p,parent;
int a;parent=user;if(user->child==NULL){ printf(“錯誤:刪除失敗,該目錄下沒有可刪除的文件(夾)!n”);return;} user=user->child;p=user;for(a=1;;a++)//找出要刪除文件的所在位置 { if(!strcmp(user->name,ch))
break;if(user->brother==NULL){
printf(“錯誤:刪除失敗,當(dāng)前位置沒有該文件!n”);
return;}
if(a>1)
p=user;user=user->brother;} if(user->open==1)//判斷文件的開關(guān)情況 {
} printf(“錯誤:刪除失敗,選擇文件處于打開狀態(tài)!n”);return;if(p==user)//被刪文件在文件隊列的開頭 { if(user->brother==NULL)//該文件隊列只有有一個文件
{
parent->child=NULL;
if(user->child!=NULL)//刪除的是文件(夾)子樹
{
deletechildtree(user);}else {
free(user);//刪除的是文件(夾)結(jié)點
} printf(“刪除成功!n”);return;} //文件隊列有多個文件 p=user->brother;
} parent->child=p;p->parent=parent;if(user->child!=NULL){ deletechildtree(user);}else { free(user);} printf(“刪除成功!n”);return;else//被刪文件不在隊列開頭 {
if(user->brother==NULL)//被刪文件在文件隊列最末尾 { p->brother=NULL;if(user->child!=NULL){
deletechildtree(user);}else {
free(user);}
} printf(“刪除成功!n”);return;
//被刪文件在文件隊列中間
p->brother=user->brother;
if(user->child!=NULL)
{
deletechildtree(user);
}
else
{
free(user);
} } printf(“刪除成功!n”);}
FFile openfolder(FFile user)/*打開文件夾*/ {
} //int a,b;//a=0;/*if(user->child==NULL){ user->child=(Ffile*)malloc(sizeof(Ffile));user->child->type=0;user->child->brother=NULL;user->child->parent=user;user->child->child=NULL;
} /*for(b=1;b<=20;b++){ if(openf[b].add!=NULL)
a++;} if(a==20){ printf(“錯誤:打開列表溢出!”);return(user);} for(b=1;;b++){ if(openf[b].add==NULL)
break;}*/
user->open=1;//設(shè)置文件為打開 //strcpy(openf[b].name,user->name);//openf[b].add=user;printf(“文件夾打開成功。n”);return(user);//返回被打開的文件夾的地址
void openfile(FFile user)/*打開普通文件*/ { if(user->open==1){
printf(“錯誤:打開失敗,此文件已經(jīng)被打開!n”);
return;} user->open=1;printf(“普通文件打開成功!n”);}
FFile openff(FFile user)/*打開文件(夾)*/ {
char ch[20];FFile parent;
int a;printf(“選擇要打開的文件名:n”);scanf(“%s”,ch);
parent=user;if(user->child==NULL){
printf(“錯誤:打開失敗,該目錄下沒有可打開的文件(夾)!n”);return(parent);} user=user->child;for(a=1;;a++)//找出要打開文件的所在位置 { if(!strcmp(user->name,ch))
break;if(user->brother==NULL){
printf(“錯誤:打開失敗,當(dāng)前位置沒有該文件!n”);
return(parent);}
user=user->brother;} if(user->type==1){
printf(“開始打開文件夾。。n”);user=openfolder(user);} else if(user->type==2){
printf(“開始打開普通文件。。n”);
openfile(user);
user=user->parent;} return(user);}
void closefile(FFile user)/*關(guān)閉普通文件*/ {
char ch[20];int a;printf(“選擇要打開的文件名:n”);scanf(“%s”,ch);if(user->child==NULL){ printf(“錯誤:關(guān)閉失敗,該目錄下沒有可關(guān)閉的文件!n”);return;} user=user->child;for(a=1;;a++)//找出要關(guān)閉文件的所在位置 { if(!strcmp(user->name,ch))
break;if(user->brother==NULL){
printf(“錯誤:關(guān)閉失敗,當(dāng)前位置沒有該文件!n”);
return;}
user=user->brother;} if(user->open==0){
printf(“錯誤:關(guān)閉失敗,該文件已經(jīng)是關(guān)閉狀態(tài)!n”);
return;} user->open=0;printf(“文件已經(jīng)成功關(guān)閉!”);} /*沒有文件夾關(guān)閉原因:
文件夾一打開就會跳向打開的新文件里 而文件夾關(guān)閉就會直接返回上一級的目錄,若想整個文件夾都關(guān)閉,直接退出就可以了 因此不會直接關(guān)閉某個特定的文件*/
FFile backf(FFile user)/*返回上一層目錄*/ { if(user->parent==NULL){
printf(“錯誤:返回失敗,此處是最頂層目錄!n”);
return(user);}
} user->open=0;user=user->parent;return(user);void readfile(FFile user)/*讀文件*/ { char ch[20];int a;
printf(“選擇要讀取的文件名:n”);scanf(“%s”,ch);if(user->child==NULL){ printf(“錯誤:讀取失敗,該目錄下沒有可讀取的文件!n”);return;} user=user->child;for(a=1;;a++)//找出要讀取文件的所在位置 { if(!strcmp(user->name,ch))
break;if(user->brother==NULL){
printf(“錯誤:讀取失敗,當(dāng)前位置沒有該文件!n”);
return;}
user=user->brother;} if(user->open==0){ printf(“錯誤:文件讀取失敗,該文件處于關(guān)閉狀態(tài)!n”);return;} else if(user->iffile.read==0){ printf(“錯誤:文件讀取失敗,該文件受保護(hù),禁止讀取!n”);return;} printf(“讀操作,該文件中的內(nèi)容:n”);if(!strcmp(user->iffile.ch,“NULL”)){ printf(“該文件內(nèi)沒有可讀內(nèi)容!n”);return;
} } printf(“%sn”,user->iffile.ch);printf(“文件讀取成功!n”);void writefile(FFile user)/*寫文件*/ { char ch[20];int a;
} printf(“選擇要進(jìn)行寫操作的文件名:n”);scanf(“%s”,ch);if(user->child==NULL){ printf(“錯誤:寫操作失敗,該目錄下沒有可寫的文件!n”);return;} user=user->child;for(a=1;;a++)//找出要讀取文件的所在位置 { if(!strcmp(user->name,ch))
break;if(user->brother==NULL){
printf(“錯誤:寫操作失敗,當(dāng)前位置沒有該文件!n”);
return;}
user=user->brother;} if(user->open==0){ printf(“錯誤:文件寫操作失敗,該文件處于關(guān)閉狀態(tài)!n”);return;} else if(user->iffile.write==0){ printf(“錯誤:文件寫操作失敗,該文件受保護(hù),禁止寫!n”);return;} printf(“寫操作,輸入內(nèi)容:n”);scanf(“%s”,user->iffile.ch);user->iffile.length=strlen(user->iffile.ch);printf(“文件進(jìn)行寫操作成功!n”);
FFile copyfile(FFile user,FFile copyf)/*拷貝文件*/ { char ch[20];int a;printf(“選擇要進(jìn)行拷貝的文件(夾)名:n”);scanf(“%s”,ch);
if(user->child==NULL){
printf(“錯誤:拷貝失敗,該目錄下沒有可拷貝的文件!n”);
return(NULL);} user=user->child;for(a=1;;a++)//找出要拷貝文件的所在位置,用user替代
{
if(!strcmp(user->name,ch))
break;
if(user->brother==NULL)
{
printf(“錯誤:拷貝失敗,當(dāng)前位置沒有該文件!n”);
return(NULL);
}
user=user->brother;} copyf=user;
} printf(“拷貝成功!n”);return(copyf);FFile fenpei(FFile copyf,FFile user,FFile parent)/*粘貼時,給已拷貝項分配內(nèi)存空間,以及給對應(yīng)信息賦值*/ { user=(Ffile*)malloc(sizeof(Ffile));
//parent對child的連接,以及brother之間的連接已經(jīng)完成if(copyf->brother==NULL && copyf->child==NULL){
user->parent=parent;
user->child=NULL;
user->brother=NULL;}
else{ if(copyf->brother!=NULL){
user->brother=fenpei(copyf->brother,user->brother,parent);//brother連接,兄弟節(jié)點有同一個父結(jié)點
user->brother->parent=user->parent;} else { user->brother=NULL;} if(copyf->child!=NULL){ //parent=p;user->child=fenpei(copyf->child,user->child,user);
user->child->parent=user;//完成child對parent的連接
//child連接,自己孩子的父結(jié)點就是自己
} else {
user->child=NULL;
user->child->parent=user;} }
//設(shè)置結(jié)點對應(yīng)的信息
strcpy(user->name,copyf->name);user->open=copyf->open;user->type=copyf->type;if(user->type==2){
user->iffile.length=copyf->iffile.length;
user->iffile.read=copyf->iffile.read;
//user->iffile.type=copyf->iffile.type;
user->iffile.write=copyf->iffile.write;
strcpy(user->iffile.ch,copyf->iffile.ch);}
return(user);}
void prastefile(FFile user,FFile copyf)/*粘貼文件*/ //user是要粘貼的地方,copyf是要粘貼的內(nèi)容,//有相同文件名的會判斷會不會覆蓋,或者是重命名 //在原樹中進(jìn)行新建操作 { int i,j;char ch[20];FFile p,user0,parent;parent=user;//記錄父結(jié)點
user=user->child;
p=user;//記錄當(dāng)前結(jié)點的前一個brother結(jié)點 strcpy(ch,“NULL”);if(copyf==NULL)//判斷有沒有拷貝文件 {
printf(“錯誤:粘貼失敗,還沒有拷貝任何文件(夾)!n”);
return;}
//p=(Ffile*)malloc(sizeof(Ffile));//p->child=(Ffile*)malloc(sizeof(Ffile));//先給粘貼項分配內(nèi)存空間
//p->child=fenpei(copyf,p->child,p);
if(user==NULL)//當(dāng)前位置沒有任何文件結(jié)點
{
} user=fenpei(copyf,user,parent);//是他自己要分配,不是孩子結(jié)點!!parent->child=user;user->brother=NULL;user->parent=parent;return;//該位置沒有任何文件 for(j=1;;j++){ if(user->type==0)//開端的空結(jié)點,用新結(jié)點覆蓋,即:當(dāng)前位置沒有文件結(jié)點
{
user=user->parent;
deletechildtree(p);
user=fenpei(copyf,user->child,user);//返還增加的結(jié)點
user->brother=NULL;
user->parent=parent;
parent->child=user;
} return;if(!strcmp(user->name,copyf->name)){
printf(“提示:該文件名已經(jīng)存在!n”);
printf(“請重命名文件:n”);
printf(“輸入新文件名:n”);
scanf(“%s”,ch);
} if(user->brother==NULL)//普通的退出條件
{
break;} p=user;user=user->brother;} user->brother=fenpei(copyf,user->brother,user->parent);user->brother->parent=user->parent;//若要更名,粘貼分配完內(nèi)存空間返回時再改變
if(strcmp(ch,“NULL”))
strcpy(user->brother->name,ch);printf(“粘貼成功。n”);}
void showroute(FFile user)/*顯示當(dāng)前路徑*/ { if(user->parent!=NULL){
showroute(user->parent);} printf(“%s/”,user->name);//路徑中每個結(jié)點的輸出項 }
void change(FFile user){ char ch[20];int a,b;
if(user->child==NULL)
{
} printf(“錯誤:屬性修改失敗,該目錄下沒有可修改的文件!n”);return;printf(“選擇要進(jìn)行屬性修改的文件(夾)名:n”);scanf(“%s”,ch);user=user->child;for(a=1;;a++)//找出要拷貝文件的所在位置,用user替代 { if(!strcmp(user->name,ch))
break;if(user->brother==NULL){
printf(“錯誤:屬性修改失敗,當(dāng)前位置沒有該文件!n”);
return;}
user=user->brother;} if(user->type==1){ printf(“錯誤:文件夾不能進(jìn)行屬性修改!n”);return;} for(;;){
printf(“1.修改讀權(quán)限;n”);printf(“2.修改寫權(quán)限;n”);printf(“3.返回;n”);printf(“選擇操作:n”);scanf(“%d”,&a);if(a==1){ printf(“0.禁止;
1.允許;n”);printf(“請選擇:n”);scanf(“%d”,&b);user->iffile.read=b;printf(“修改成功!n”);} else if(a==2){ printf(“0.禁止;
1.允許;n”);printf(“請選擇:n”);scanf(“%d”,&b);user->iffile.write=b;
}
} printf(“修改成功!n”);} else if(a==3){ return;} else { } printf(“錯誤:沒有該操作!n”);void main()/*主函數(shù)*/ {
FFile d,e,f;//f記錄當(dāng)前顯示界面父結(jié)點位置 int a,b,c;char ch[20];a=0;printf(“******************************目錄******************************n”);printf(“
1.選擇用戶n”);printf(“
2.退出n”);
printf(“****************************************************************n”);for(;;){
printf(“選擇操作:n”);scanf(“%d”,&a);if(a==1){ printf(“選擇用戶:n”);printf(“1.user1;n2.user2;n”);scanf(“%d”,&b);break;} else if(a==2){ printf(“歡迎使用。n”);exit(0);//系統(tǒng)退出的操作碼 } else { printf(“錯誤:沒有該操作!n”);
} } //初始化打開列表 //initopen();//初始化各個用戶的信息
//copyf=(Ffile*)malloc(sizeof(Ffile));//copyf=NULL;copyf=NULL;user1=init();strcpy(user1->name,“user1”);user2=init();strcpy(user2->name,“user2”);d=init();e=init();user1->child=d;user2->child=e;d->parent=user1;e->parent=user2;printf(“%d”,user1->child->type);if(b==1){ printf(“已經(jīng)進(jìn)入user1系統(tǒng)n”);f=user1;show(user1);}else{
} printf(“已經(jīng)進(jìn)入user2系統(tǒng)n”);f=user2;show(user2);
for(;;){ printf(“****************************************************************n”);printf(“1.創(chuàng)建文件(夾)
5.讀文件
9.顯示當(dāng)前路徑
n”);printf(“2.刪除文件(夾)
6.寫文件
10.返回上一層目錄
n”);printf(“3.打開文件(夾)
7.拷貝文件
11.改變普通文件屬性n”);printf(“4.關(guān)閉普通文件
8.粘貼文件
12.退出n”);printf(“****************************************************************n”);printf(“選擇操作:n”);scanf(“%d”,&c);if(c==12){
break;}else if(c==1){ creatf(f);} else if(c==2){
printf(“選擇要刪除的文件(夾)的名字:n”);scanf(“%s”,ch);deletefile(f,ch);} else if(c==3){ f=openff(f);} else if(c==4){ closefile(f);} else if(c==5){ readfile(f);} else if(c==6){ writefile(f);} else if(c==7){ copyf=copyfile(f,copyf);} else if(c==8){ prastefile(f,copyf);copyf=NULL;} else if(c==9){ printf(“路徑為:n”);showroute(f);printf(“n”);} else if(c==10){
}
f=backf(f);
} else if(c==11){ change(f);} else { continue;} show(f);} printf(“歡迎使用!n”);
第二篇:操作系統(tǒng)課程設(shè)計++模擬磁盤文件管理的程序
中南林業(yè)科技大學(xué)
操作系統(tǒng)課程設(shè)計
課程題目:模擬磁盤文件管理的程序
姓名: 學(xué)號:
專業(yè): 計算機(jī)科學(xué)與技術(shù) 年級:
2006
計算機(jī)科學(xué)學(xué)院
2008年11月 模擬磁盤文件管理的程序
一、課程設(shè)計內(nèi)容
⑴ 自定義磁盤文件管理的數(shù)據(jù)結(jié)構(gòu); ⑵ 能夠自由創(chuàng)建、修改、刪除文件; ⑶ 文件具有一定自定義的屬性; ⑷ 能夠顯示當(dāng)前系統(tǒng)文件的狀態(tài)。
二、課程設(shè)計的數(shù)據(jù)結(jié)構(gòu)說明
程序中定義了兩個類: class file//文件類 {private: char name[10];//文件名 public: int tag;//刪除標(biāo)記 1:已刪 0:未刪 file(){ } char *getname(){return name;} //獲取文件名
int gettag(){return tag;} //獲取刪除標(biāo)記
int getlength(){return length;} //獲取文件大小
int getblocknum(){return blocknum;} // 磁盤塊數(shù)
int getblocksum1(){return blocksum1;} //磁盤塊號的始點 int getblocksum2(){return blocksum2;} //磁盤塊號的終點 int length,blocknum,blocksum1,blocksum2;
void setname(char na[ ]){strcpy(name,na);} //設(shè)置文件名 void delwenjian(){ tag=1;}//設(shè)置刪除標(biāo)記 1:已刪 0:未刪
void creatfile(char *na,int L,int num,int s1,int s2)//創(chuàng)建文件 void deltefile(char *na){tag=1;strcpy(name,na);} //刪除文件 void disp()//輸出文件信息 class fdatabase //文件庫類 { private: int top;//文件記錄指針 file f[50];public: fdatabase(){top=-1;} //構(gòu)造函數(shù) int search(char *fname)//按文件名查找
int creatfile(char *na,int L,int num,int s1,int s2)//創(chuàng)建文件時先查找是否存在
int deltefile(char *na)//刪除文件時先查找是否存在 void disp()//輸出所有文件信息 };
三、課程設(shè)計的模板說明
1、初始化,建立文件系統(tǒng)
輸入磁盤大?。℅),每個盤塊大小(M),自動建立位示圖,位示圖字長定為32位
輸出位示圖的行數(shù),以及行號、列號與磁盤塊號的轉(zhuǎn)換公式(都從0開始編號)。
2、循環(huán)選擇執(zhí)行以下功能
1、存儲文件
輸入建立的文件名和文件大小,如果該文件名已經(jīng)存在,則輸出不能建立的信息否則計算所需的磁盤塊數(shù)
為其分配足夠多的磁盤塊,并記錄下來 輸出所占用的磁盤塊號
2、刪除文件
輸入要刪除的文件名,如果該文件名不存在,則輸出刪除錯誤信息,否則收回該文件所占用的磁盤塊 刪除該文件名
3、顯示位示圖情況
顯示位示圖的情況 顯示剩余磁盤塊的數(shù)目
4、顯示文件列表
顯示文件名,文件大小,占用的磁盤塊數(shù)目和磁盤塊號
四、課程設(shè)計的源代碼
#include
char name[10];//文件名 public: int tag;//刪除標(biāo)記 1:已刪 0:未刪 file(){ } char *getname(){return name;} //獲取姓名
int gettag(){return tag;} //獲取刪除標(biāo)記
int getno(){return no;} //獲取文件編號
int getlength(){return length;} //獲取文件大小
int getblocknum(){return blocknum;} // 磁盤塊數(shù) int getblocksum1()//磁盤塊號的始點 { return blocksum1;} int getblocksum2()//磁盤塊號的終點 { return blocksum2;} int length;//文件大小
int blocknum;//盤塊數(shù)
int blocksum1;//所占盤塊號的始點
int blocksum2;//所占盤塊號的終點
void setname(char na[ ])//設(shè)置文件名
{strcpy(name,na);} void delwenjian(){ tag=1;}//設(shè)置刪除標(biāo)記 1:已刪 0:未刪
void creatfile(char *na,int L,int num,int s1,int s2)//創(chuàng)建文件 { tag=0;length=L;blocknum=num;blocksum1=s1;blocksum2=s2;strcpy(name,na);blocknum=length/m;//盤塊數(shù)=文件大小/盤塊大小 if(length%m!=0)//盤塊數(shù)取上整 blocknum=blocknum+1;cout<<“ 所需磁盤塊數(shù):”< for(;j<32;j++) a[i][j]=1;i=i+1;for(j=0;j<(sum+blocknum)-32;j++)//再進(jìn)行剩余項賦值 { a[i][j]=1;} sum=sum+blocknum-32;} tt=tt+blocknum;//輸出文件所占用的盤塊號 cout<<“ 所占磁盤塊號:”< { for(ii=0;ii<=top;ii++) { if(strcmp(f[ii].getname(),fname)==0 && f[ii].tag==0) return 0; } return 1;} int creatfile(char *na,int L,int num,int s1,int s2)//創(chuàng)建文件時先查找是否存在 { int p;p=search(na); if(p==1) { top++; f[top].creatfile(na,L,num,s1,s2); return 1;} else {cout<<“!!該文件已存在,不能創(chuàng)建!!nn”; return 0;} } int deltefile(char *na)//刪除文件時先查找是否存在{int b,p,x=0,n1,n2,q1,q2,t;p=search(na);if(p==0)//若文件存在 { //進(jìn)行刪除文件賦值 f[ii].tag=1;b=f[ii].length/m;//盤塊數(shù)=當(dāng)前文件大小/盤塊大小 if(ii==0)// 對第一個刪除文件進(jìn)行賦值 for(k=0;k a[x][k]=0; else{ n1=(f[ii-1].blocksum2+1)/32;//被查找的文件之前文件所占用的盤塊數(shù) /32,//大于0表示跨行 n2=(f[ii].blocksum2+1)/32;//所有文件所占用的盤塊數(shù)/32,大于0表示跨行 q1=(f[ii-1].blocksum2+1)-n1*32;// 當(dāng)前文件的開始盤塊號 q2=(f[ii].blocksum2+1)-n2*32;// 用于跨行后計算盤塊號 t=n2-n1;if(t==0)//若n2與n1相等,表明當(dāng)前所有被占用盤塊在同一行 for(k=q1;k<1+b;k++) a[n2][k]=0; else { if((f[ii-1].blocksum2+1)%32==0)//前面所占用的盤塊數(shù)是32倍數(shù) { x=x+n1;//當(dāng)前文件賦值 for(;t-1>=0;t--,x++)//循環(huán)進(jìn)行整行賦值 for(k=0;k<32;k++) a[x][k]=0; x=n2;//對剩余項賦值 for(k=0;k a[x][k]=0; } else //對當(dāng)前文件前幾項賦值 { x=n1; for(k=q1;k<32;k++) a[x][k]=0;x=x+1;int t1=t; for(;t-1>0;t--,x++)//中間整行賦值 for(k=0;k<32;k++) a[x][k]=0; x=n2;//最后剩余項賦值 for(k=0;k<(f[ii].blocksum2+1)-t1*32;k++) a[x][k]=0; } } return 1;} } else {cout<<“該文件不存在”; return 0;} } void disp()//輸出所有文件信息 { for(int i=0;i<=top;i++) if(f[i].tag==0) f[i].disp();} };void bit_map(int I){ int s=0;cout<<“-”< cout< out<<“--”< a[i][j]=0; cout<<“ 建立的位示圖為:”< cout<<“ 行數(shù):”< cout <<“ttt1 存 儲 文 件nnttt2 刪 除 文 件 nnttt3 顯示位示圖情況 nnttt4 顯示文件列表”< case '1': cout <<“ 請輸入文件名: ”; cin>>fname; cout< if(q==0) { cout<<“!!該文件已存在,不能創(chuàng)建!!nn”; break;} cout <<“ 請輸入文件大小MB: ”; cin>>l; cout< if(l>g*1024) {cout<<“!!文件大小超過磁盤最大容量,無法進(jìn)行分配!!”< break;} p.creatfile(fname,l,b,ss1,ss2); break; case '2': cout <<“ 請輸入文件名: ”; cin>>fname; cout< q=p.search(fname); if(!q==0) { cout<<“!!該文件不存在,無法刪除!!nn ”; break; } p.deltefile(fname); break;case '3': cout <<“tt**************顯示位示圖如下*********************n”; bit_map(I); cout< break; case '4': cout <<“tt*************文件列表如下************************n”;cout<<“-”< p.disp(); cout< break;default: cout<<“輸入錯誤,請從新輸入: nn”; break;} } } 五、課程設(shè)計程序運(yùn)行結(jié)果 1、初始化,建立文件系統(tǒng) (1)用戶根據(jù)提示輸入磁盤大?。℅B)與每個盤塊大?。∕B); (2)程序首先根據(jù)用戶輸入的磁盤大?。℅B)與每個盤塊大?。∕B),自動建立位示圖,即初始化位示圖,位示圖每一行長度固定為32位(即列固定為32);位示圖中每一位表示一個盤塊,取值0和1分別表示空閑和占用。初始化的位示圖應(yīng)全為0; (3)程序再輸出位示圖的剩余盤塊數(shù),行數(shù),以及行號、列號與磁盤塊號的轉(zhuǎn)換公式(行列皆從0開始編號); 這樣,初始化,建立文件系統(tǒng)完成。運(yùn)行結(jié)果: 2、選擇執(zhí)行:存儲文件,刪除文件,顯示位示圖情況,顯示文件列表 【顯示文件管理系統(tǒng)列表】顯示文件系統(tǒng)管理列表,并提示輸入信息1——4。用戶輸入文件操作命令1(存儲文件),2(刪除文件)、3(顯示位示圖情況)、4(顯示文件列表); 格式如下:鍵入1,創(chuàng)建文件名為fname,大小為L(MB)的文件; 鍵入2,刪除文件名為fname的文件; 鍵入3,顯示位示圖情況; 鍵入4,顯示所有文件信息。 運(yùn)行結(jié)果: 【存儲文件】 用戶輸入文件操作命令是1(存儲文件)。系統(tǒng)提示你輸入你要建立的文件名和文件大小,如果該文件名已經(jīng)存在,則系統(tǒng)提示輸出不能建立此文件的信息,否則計算所需的磁盤塊數(shù)和所占用的磁盤塊號,并輸出結(jié)果。相應(yīng)的在位示圖上,因為位示圖是矩陣,可以用數(shù)組存儲,根據(jù)所占用的磁盤塊號和公式: 磁盤塊號=行號*32+列號 行號=磁盤塊號/32 列號=磁盤塊號%32 計算出文件占用的磁盤塊在位示圖上的位置,現(xiàn)在是創(chuàng)建文件,所以將位示圖該位置上的二進(jìn)制數(shù)置1,表示已分配出去。 分別創(chuàng)建名為ll,zz和mm三個文件,文件大小分別為224MB,320MB和56MB。 此時對應(yīng)的位示圖如下: 文件列表如下: 若再創(chuàng)建一個已經(jīng)創(chuàng)建過的文件,則顯示如下信息: 若創(chuàng)建的文件大小超過磁盤的最大容量,則顯示如下信息: 【刪除文件】 用戶輸入文件操作命令是2(刪除文件)。系統(tǒng)提示你輸入要刪除的文件名,如果該文件名不存在,則輸出刪除出錯信息。在位示圖上,根據(jù)所占用的磁盤塊號和公式: 磁盤塊號=行號*32+列號 行號=磁盤塊號/32 列號=磁盤塊號%32 計算出文件占用的磁盤塊在位示圖上的位置,現(xiàn)在是刪除文件,所以將位示圖該位置上的二進(jìn)制數(shù)置0,表示收回該文件所占用的磁盤塊。刪除第二個文件zz,結(jié)果如下: 則相應(yīng)的位示圖和文件列表變?yōu)椋?/p> 若刪除一個不存在的文件,則顯示如下信息: 【顯示位示圖情況】 如果用戶輸入文件操作命令是我wst()(顯示位示圖情況),系統(tǒng)輸出此時位示圖的情況,狀態(tài)位為'0'表示對應(yīng)盤塊空閑,狀態(tài)位為'1'表示該盤塊已被分配出去。系統(tǒng)再顯示剩余磁盤塊的數(shù)目。 以下是刪除zz文件,創(chuàng)建xx后和創(chuàng)建xx后,刪除ll的位示圖: 【顯示文件列表】 如果用戶輸入文件操作命令是disp()(顯示所有文件情況),系統(tǒng)會顯示所有文件的文件名,文件大小,占用的盤塊數(shù)和盤塊號。 以下是刪除zz文件,創(chuàng)建xx后和創(chuàng)建xx后,刪除ll顯示的文件列表: 操作系統(tǒng)課程設(shè)計 注意事項: 0.請每位同學(xué)必須按時提交課程設(shè)計報告(包括電子版和紙質(zhì)版),算入期末成績 1.在三個題目中選擇一個 2.如果選擇題目 (一)進(jìn)程調(diào)度算法,要求實現(xiàn)其中2個以上(包括2個)進(jìn)程調(diào)度算法 3.如果選擇題目 (二)銀行家算法,要求能夠判斷系統(tǒng)的安全狀態(tài) 4.如果選擇題目 (三)頁面調(diào)度算法,要求實現(xiàn)其中2個以上(包含2個)進(jìn)程調(diào)度算法 5.報告應(yīng)包含算法分析、實驗截圖、核心算法源代碼,請各位同學(xué)認(rèn)真對待,獨立完成 6.提交要求:電子版(包括實驗程序)請發(fā)至ropeal@163.com,紙質(zhì)版請班長收齊,由班長統(tǒng)一在課堂上提交(并提交未交人員名單),截止時間第16周周三(2014.1.31)7.格式要求: 7.1 A4紙10頁左右 7.2 封面請注明班級、姓名、學(xué)號、所選題目 7.3 電子版發(fā)送時,請打包成一個文件,將文件名設(shè)置為:學(xué)號+姓名+題目名稱(如20130000張三進(jìn)程調(diào)度算法課程設(shè)計),郵件主題同文件名 一、進(jìn)程調(diào)度算法 1.1 實驗?zāi)康模? a、設(shè)計進(jìn)程控制塊PCB表結(jié)構(gòu),模擬實現(xiàn)進(jìn)程調(diào)度算法:FIFO,靜態(tài)優(yōu)先級調(diào)度,時間片輪轉(zhuǎn)調(diào)度,多級反饋隊列調(diào)度。(實現(xiàn)其中之二)。* b、建立進(jìn)程就緒隊列。對不同算法編制入鏈子程序。c、編寫一進(jìn)程調(diào)度程序模擬程序。模擬程序只對PCB進(jìn)行相應(yīng)的調(diào)度模擬操作,不需要實際程序。* 由用戶輸入進(jìn)程名和進(jìn)程長度,然后按照短進(jìn)程優(yōu)先的進(jìn)程處理順序給出進(jìn)程的排序。 1.2 實驗原理 調(diào)度算法是指:根據(jù)系統(tǒng)的資源分配策略所規(guī)定的資源分配算法。1.2.1 先來先服務(wù)和短作業(yè)(進(jìn)程)優(yōu)先調(diào)度算法 1.先來先服務(wù)調(diào)度算法。先來先服務(wù)(FCFS)調(diào)度算法是一種最簡單的調(diào)度算法,該算法既可用于作業(yè)調(diào)度,也可用于進(jìn)程調(diào)度。FCFS算法比較有利于長作業(yè)(進(jìn)程),而不利于短作業(yè)(進(jìn)程)。由此可知,本算法適合于CPU繁忙型作業(yè),而不利于I/O繁忙型的作業(yè)(進(jìn)程)。 2.短作業(yè)(進(jìn)程)優(yōu)先調(diào)度算法。短作業(yè)(進(jìn)程)優(yōu)先調(diào)度算法(SJ/PF)是指對短作業(yè)或短進(jìn)程優(yōu)先調(diào)度的算法,該算法既可用于作業(yè)調(diào)度,也可用于進(jìn)程調(diào)度。但其對長作業(yè)不利;不能保證緊迫性作業(yè)(進(jìn)程)被及時處理;作業(yè)的長短只是被估算出來的。1.2.2 高優(yōu)先權(quán)優(yōu)先調(diào)度算法 1.優(yōu)先權(quán)調(diào)度算法的類型。為了照顧緊迫性作業(yè),使之進(jìn)入系統(tǒng)后便獲得優(yōu)先處理,引入了最高優(yōu)先權(quán)優(yōu)先(FPF)調(diào)度算法。此算法常被用在批處理系統(tǒng)中,作為作業(yè)調(diào)度算法,也作為多種操作系統(tǒng)中的進(jìn)程調(diào)度,還可以用于實時系統(tǒng)中。當(dāng)其用于作業(yè)調(diào)度,將后備隊列中若干個優(yōu)先權(quán)最高的作業(yè)裝入內(nèi)存。當(dāng)其用于進(jìn)程調(diào)度時,把處理機(jī)分配給就緒隊列中優(yōu)先權(quán)最高的進(jìn)程,此時,又可以進(jìn)一步把該算法分成以下兩種: 1)非搶占式優(yōu)先權(quán)算法 2)搶占式優(yōu)先權(quán)調(diào)度算法(高性能計算機(jī)操作系統(tǒng)) 2.優(yōu)先權(quán)類型。對于最高優(yōu)先權(quán)優(yōu)先調(diào)度算法,其核心在于:它是使用靜態(tài)優(yōu)先權(quán)還是動態(tài)優(yōu)先權(quán),以及如何確定進(jìn)程的優(yōu)先權(quán)。3.高響應(yīng)比優(yōu)先調(diào)度算法 為了彌補(bǔ)短作業(yè)優(yōu)先算法的不足,我們引入動態(tài)優(yōu)先權(quán),使作業(yè)的優(yōu)先等級隨著等待時間的增加而以速率a提高。該優(yōu)先權(quán)變化規(guī)律可描述為:優(yōu)先權(quán)=(等待時間+要求服務(wù)時間)/要求服務(wù)時間;即 =(響應(yīng)時間)/要求服務(wù)時間 1.2.3 基于時間片的輪轉(zhuǎn)調(diào)度算法 1.時間片輪轉(zhuǎn)法。時間片輪轉(zhuǎn)法一般用于進(jìn)程調(diào)度,每次調(diào)度,把CPU分配隊首進(jìn)程,并令其執(zhí)行一個時間片。當(dāng)執(zhí)行的時間片用完時,由一個記時器發(fā)出一個時鐘中斷請求,該進(jìn)程被停止,并被送往就緒隊列末尾;依次循環(huán)。2.多級反饋隊列調(diào)度算法 多級反饋隊列調(diào)度算法多級反饋隊列調(diào)度算法,不必事先知道各種進(jìn)程所需要執(zhí)行的時間,它是目前被公認(rèn)的一種較好的進(jìn)程調(diào)度算法。其實施過程如下: 1)設(shè)置多個就緒隊列,并為各個隊列賦予不同的優(yōu)先級。在優(yōu)先權(quán)越高的隊列中,為每個進(jìn)程所規(guī)定的執(zhí)行時間片就越小。 2)當(dāng)一個新進(jìn)程進(jìn)入內(nèi)存后,首先放入第一隊列的末尾,按FCFS原則排隊等候調(diào)度。如果他能在一個時間片中完成,便可撤離;如果未完成,就轉(zhuǎn)入第二隊列的末尾,在同樣等待調(diào)度?? 如此下去,當(dāng)一個長作業(yè)(進(jìn)程)從第一隊列依次將到第n隊列(最后隊列)后,便按第n隊列時間片輪轉(zhuǎn)運(yùn)行。3)僅當(dāng)?shù)谝魂犃锌臻e時,調(diào)度程序才調(diào)度第二隊列中的進(jìn)程運(yùn)行;僅當(dāng)?shù)?到第(i-1)隊列空時,才會調(diào)度第i隊列中的進(jìn)程運(yùn)行,并執(zhí)行相應(yīng)的時間片輪轉(zhuǎn)。4)如果處理機(jī)正在處理第i隊列中某進(jìn)程,又有新進(jìn)程進(jìn)入優(yōu)先權(quán)較高的隊列,則此新隊列搶占正在運(yùn)行的處理機(jī),并把正在運(yùn)行的進(jìn)程放在第i隊列的隊尾。 1.3 實驗要求 a、使用模塊化設(shè)計思想來設(shè)計; b、給出算法的流程圖或偽碼說明。c、學(xué)生可按照自身條件,隨意選擇采用的算法,(例如:采用冒泡法編寫程序,實現(xiàn)短進(jìn)程優(yōu)先調(diào)度的算法) d、進(jìn)程調(diào)度程序模擬程序只對PCB進(jìn)行相應(yīng)的調(diào)度模擬操作,不需要實際程序。 1.4 算法簡析 a、每個進(jìn)程可有三個狀態(tài),并假設(shè)初始狀態(tài)為就緒狀態(tài)。b、為了便于處理,程序中的某進(jìn)程運(yùn)行時間以時間片為單位計算。各進(jìn)程的優(yōu)先數(shù)或輪轉(zhuǎn)時間數(shù)以及進(jìn)程需運(yùn)行的時間片數(shù)的初始值均由用戶給定。c、在優(yōu)先數(shù)算法中,優(yōu)先數(shù)可以先取值為(50-該進(jìn)程所需時間),進(jìn)程每執(zhí)行一次,優(yōu)先數(shù)減3,CPU時間片數(shù)(CPUtime)加1,* 進(jìn)程還需要的時間片數(shù)(needtime)減1。在時間片輪轉(zhuǎn)算法中,采用固定時間片 (即:每執(zhí)行一次進(jìn)程,該進(jìn)程的執(zhí)行時間片數(shù)為已執(zhí)行了2個單位),這時,CPU時間片(CPUtime)數(shù)加2,* 進(jìn)程還需要的時間片數(shù)(needtime)減2,并排列到就緒隊列的尾上。 d、對于遇到優(yōu)先數(shù)一致的情況,采用FIFO策略解決。 二、銀行家算法 2.1 概述 2.1.1 設(shè)計目的1、了解多道程序系統(tǒng)中,多個進(jìn)程并發(fā)執(zhí)行的資源分配。 2、掌握死鎖的產(chǎn)生的原因、產(chǎn)生死鎖的必要條件和處理死鎖的基本方法。 3、掌握預(yù)防死鎖的方法,系統(tǒng)安全狀態(tài)的基本概念。 4、掌握銀行家算法,了解資源在進(jìn)程并發(fā)執(zhí)行中的資源分配策略。 5、理解死鎖避免在當(dāng)前計算機(jī)系統(tǒng)不常使用的原因 2.2 關(guān)于死鎖 2.2.1 死鎖概念: 在多道程序系統(tǒng)中,雖可借助于多個進(jìn)程的并發(fā)執(zhí)行,來改善系統(tǒng)的資源利用率,提高系統(tǒng)的吞吐量,但可能發(fā)生一種危險━━死鎖。所謂死鎖(Deadlock),是指多個進(jìn)程在運(yùn)行中因爭奪資源而造成的一種僵局(Deadly_Embrace),當(dāng)進(jìn)程處于這種僵持狀態(tài)時,若無外力作用,它們都將無法再向前推進(jìn)。一組進(jìn)程中,每個進(jìn)程都無限等待被該組進(jìn)程中另一進(jìn)程所占有的資源,因而永遠(yuǎn)無法得到的資源,這種現(xiàn)象稱為進(jìn)程死鎖,這一組進(jìn)程就稱為死鎖進(jìn)程。 2.2.2 關(guān)于死鎖的一些結(jié)論: 參與死鎖的進(jìn)程最少是兩個(兩個以上進(jìn)程才會出現(xiàn)死鎖) 參與死鎖的進(jìn)程至少有兩個已經(jīng)占有資源 參與死鎖的所有進(jìn)程都在等待資源 參與死鎖的進(jìn)程是當(dāng)前系統(tǒng)中所有進(jìn)程的子集 注:如果死鎖發(fā)生,會浪費(fèi)大量系統(tǒng)資源,甚至導(dǎo)致系統(tǒng)崩潰。 2.2.3 資源分類: 永久性資源: 可以被多個進(jìn)程多次使用(可再用資源),分為:可搶占資源與不可搶占資源 臨時性資源:只可使用一次的資源;如信號量,中斷信號,同步信號等(可消耗性資源) “申請--分配--使用--釋放”模式 2.2.4 產(chǎn)生死鎖的四個必要條件: 1、互斥使用(資源獨占) 一個資源每次只能給一個進(jìn)程使用 2、不可強(qiáng)占(不可剝奪) 資源申請者不能強(qiáng)行的從資源占有者手中奪取資源,資源只能由占有者自愿釋放 3、請求和保持(部分分配,占有申請) 一個進(jìn)程在申請新的資源的同時保持對原有資源的占有(只有這樣才是動態(tài)申請,動態(tài)分配) 4、循環(huán)等待 存在一個進(jìn)程等待隊列 {P1 , P2 , ? , Pn},其中P1等待P2占有的資源,P2等待P3占有的資源,?,Pn等待P1占有的資源,形成一個進(jìn)程等待環(huán)路 2.2.5 死鎖的解決方案 1 產(chǎn)生死鎖的例子 申請不同類型資源產(chǎn)生死鎖 P1: ? 申請打印機(jī) 申請掃描儀 使用 釋放打印機(jī) 釋放掃描儀 ? P2: ? 申請掃描儀 申請打印機(jī) 使用 釋放打印機(jī) 釋放掃描儀 ? 申請同類資源產(chǎn)生死鎖(如內(nèi)存) 設(shè)有資源R,R有m個分配單位,由n個進(jìn)程P1,P2,?,Pn(n > m)共享。假設(shè)每個進(jìn)程對R的申請和釋放符合下列原則: * 一次只能申請一個單位 * 滿足總申請后才能使用 * 使用完后一次性釋放 m=2,n=3 資源分配不當(dāng)導(dǎo)致死鎖產(chǎn)生 2死鎖預(yù)防: 定義:在系統(tǒng)設(shè)計時確定資源分配算法,保證不發(fā)生死鎖。具體的做法是破壞產(chǎn)生死鎖的四個必要條件之一 ①破壞“不可剝奪”條件 在允許進(jìn)程動態(tài)申請資源前提下規(guī)定,一個進(jìn)程在申請新的資源不能立即得到滿足而變?yōu)榈却隣顟B(tài)之前,必須釋放已占有的全部資源,若需要再重新申請 ②破壞“請求和保持”條件 要求每個進(jìn)程在運(yùn)行前必須一次性申請它所要求的所有資源,且僅當(dāng)該進(jìn)程所要資源均可滿足時才給予一次性分配 ③破壞“循環(huán)等待”條件 采用資源有序分配法: 把系統(tǒng)中所有資源編號,進(jìn)程在申請資源時必須嚴(yán)格按資源編號的遞增次序進(jìn)行,否則操作系統(tǒng)不予分配。 2.2.6 安全狀態(tài)與不安全狀態(tài) 安全狀態(tài): 如果存在一個由系統(tǒng)中所有進(jìn)程構(gòu)成的安全序列P1,?Pn,則系統(tǒng)處于安全狀態(tài)。一個進(jìn)程序列{P1,?,Pn}是安全的,如果對于每一個進(jìn)程Pi(1≤i≤n),它以后尚需要的資源量不超過系統(tǒng)當(dāng)前剩余資源量與所有進(jìn)程Pj(j < i)當(dāng)前占有資源量之和,系統(tǒng)處于安全狀態(tài)(安全狀態(tài)一定是沒有死鎖發(fā)生的)。 不安全狀態(tài):不存在一個安全序列,不安全狀態(tài)一定導(dǎo)致死鎖。 2.3 數(shù)據(jù)結(jié)構(gòu)設(shè)計 1.可利用資源向量矩陣AVAILABLE。這是一個含有m個元素的數(shù)組,其中的每一個元素代表一類可利用的資源數(shù)目,其初始值是系統(tǒng)中所配置的該類全部可用資源的數(shù)目,其數(shù)值隨該類資源的分配和回收而動態(tài)地改變。如果AVAILABLE [j]= K,則表示系統(tǒng)中現(xiàn)有R類資源K個 2.最大需求矩陣MAX。這是一個n*m的矩陣,用以表示每一個進(jìn)程對m類資源的最大需求。如果MAX [i,j]=K,則表示進(jìn)程i需要R類資源的數(shù)目為K。 3.分配矩陣ALLOCATION。這也是一個n*m的矩陣,它定義了系統(tǒng)中每一類資源當(dāng)前已分配給每一進(jìn)程的資源數(shù)。如果ALLOCATION [i,j]=K,則表示進(jìn)程i當(dāng)前已分得R類資源的數(shù)目為K。 4.需求矩陣NEED。這也是一個n*m的矩陣,用以表示每一個進(jìn)程尚需的各類資源數(shù)。如果NEED [i,j]=K,則表示進(jìn)程i還需要R類資源K個,才能完成其任務(wù)。上述矩陣存在下述關(guān)系: NEED [i,j]= MAX[i,j]﹣ ALLOCATION[i,j] 2.4 算法的實現(xiàn) 2.4.1 初始化 由用戶輸入數(shù)據(jù),分別對可利用資源向量矩陣AVAILABLE、最大需求矩陣MAX、分配矩陣ALLOCATION、需求矩陣NEED賦值。2.4.2 銀行家算法 在避免死鎖的方法中,所施加的限制條件較弱,有可能獲得令人滿意的系統(tǒng)性能。在該方法中把系統(tǒng)的狀態(tài)分為安全狀態(tài)和不安全狀態(tài),只要能使系統(tǒng)始終都處于安全狀態(tài),便可以避免發(fā)生死鎖。 銀行家算法的基本思想是分配資源之前,判斷系統(tǒng)是否是安全的;若是,才分配。它是最具有代表性的避免死鎖的算法。 設(shè)進(jìn)程cusneed提出請求REQUEST [i],則銀行家算法按如下規(guī)則進(jìn)行判斷。(1)如果REQUEST [cusneed] [i]<= NEED[cusneed][i],則轉(zhuǎn)(2);否則,出錯。 (2)如果REQUEST [cusneed] [i]<= AVAILABLE[cusneed][i],則轉(zhuǎn)(3);否則,出錯。(3)系統(tǒng)試探分配資源,修改相關(guān)數(shù)據(jù): AVAILABLE[i]-=REQUEST[cusneed][i];ALLOCATION[cusneed][i]+=REQUEST[cusneed][i];NEED[cusneed][i]-=REQUEST[cusneed][i];(4)系統(tǒng)執(zhí)行安全性檢查,如安全,則分配成立;否則試探險性分配作廢,系統(tǒng)恢復(fù)原狀,進(jìn)程等待。 2.4.3 安全性檢查算法 (1)設(shè)置兩個工作向量Work=AVAILABLE;FINISH(2)從進(jìn)程集合中找到一個滿足下述條件的進(jìn)程,F(xiàn)INISH==false;NEED<=Work;如找到,執(zhí)行(3);否則,執(zhí)行(4)(3)設(shè)進(jìn)程獲得資源,可順利執(zhí)行,直至完成,從而釋放資源。 Work+=ALLOCATION;Finish=true;GOTO 2(4)如所有的進(jìn)程Finish= true,則表示安全;否則系統(tǒng)不安全。 三、頁面調(diào)度算法 3.1 實驗名稱 頁式虛擬存儲管理:頁面調(diào)度算法 3.2 實驗?zāi)康?/p> 頁式虛擬存儲器實現(xiàn)的一個難點是設(shè)計頁面調(diào)度(置換)算法,即將新頁面調(diào)入內(nèi)存時,如果內(nèi)存中所有的物理頁都已經(jīng)分配出去,就要按某種策略來廢棄某個頁面,將其所占據(jù)的物理頁釋放出來,供新頁面使用。本實驗的目的是通過編程實現(xiàn)幾種常見的頁面調(diào)度(置換)算法,加深讀者對頁面思想的理解。3.3 實驗原理 頁面調(diào)度算法 目前有許多頁面調(diào)度算法,本實驗主要涉及先進(jìn)先出調(diào)度算法、最近最少調(diào)度算法、最近最不常用調(diào)度算法。本實驗使用頁面調(diào)度算法時作如下假設(shè),進(jìn)程在創(chuàng)建時由操作系統(tǒng)為之分配一個固定數(shù)目物理頁,執(zhí)行過程中物理頁的數(shù)目和位置不會改變。也即進(jìn)程進(jìn)行頁面調(diào)度時只能在分到的幾個物理頁中進(jìn)行。 下面對各調(diào)度算法的思想作一介紹。 <1> 先進(jìn)先出調(diào)度算法 先進(jìn)先出調(diào)度算法根據(jù)頁面進(jìn)入內(nèi)存的時間先后選擇淘汰頁面,先進(jìn)入內(nèi)存的頁面先淘汰,后進(jìn)入內(nèi)存的后淘汰。本算法實現(xiàn)時需要將頁面按進(jìn)入內(nèi)存的時間先后組成一個隊列,每次調(diào)度隊首頁面予以淘汰。 <2>最近最少調(diào)度算法 先進(jìn)先出調(diào)度算法沒有考慮頁面的使用情況,大多數(shù)情況下性能不佳。根據(jù)程序執(zhí)行的局部性特點,程序一旦訪問了某些代碼和數(shù)據(jù),則在一段時間內(nèi)會經(jīng)常訪問他們,因此最近最少用調(diào)度在選擇淘汰頁面時會考慮頁面最近的使用,總是選擇在最近一段時間以來最少使用的頁面予以淘汰。算法實現(xiàn)時需要為每個頁面設(shè)置數(shù)據(jù)結(jié)構(gòu)記錄頁面自上次訪問以來所經(jīng)歷的時間。 <3>最近最不常用調(diào)度算法 由于程序設(shè)計中經(jīng)常使用循環(huán)結(jié)構(gòu),根據(jù)程序執(zhí)行的局部性特點,可以設(shè)想在一段時間內(nèi)經(jīng)常被訪問的代碼和數(shù)據(jù)在將來也會經(jīng)常被訪問,顯然這樣的頁面不應(yīng)該被淘汰。最近最不常用調(diào)度算法總是根據(jù)一段時間內(nèi)頁面的訪問次數(shù)來選擇淘汰頁面,每次淘汰訪問次數(shù)最少的頁面。算法實現(xiàn)時需要為每個頁面設(shè)置計數(shù)器,記錄訪問次數(shù)。計數(shù)器由硬件或操作系統(tǒng)自動定時清零。 缺頁調(diào)度次數(shù)和缺頁中斷率、缺頁置換率計算 缺頁中斷次數(shù)是缺頁時發(fā)出缺頁中斷的次數(shù)。 缺頁中斷率=缺頁中斷次數(shù)/總的頁面引用次數(shù)*100% 缺頁調(diào)度次數(shù)是調(diào)入新頁時需要進(jìn)行頁面調(diào)度的次數(shù) 缺頁置換率=缺頁調(diào)度次數(shù)/總的頁面引用次數(shù)*100% 3.4 實驗內(nèi)容 (1)設(shè)計程序?qū)崿F(xiàn)以上三種頁面調(diào)度算法,要求: ①.可以選擇頁面調(diào)度算法類型; ②.可以為進(jìn)程設(shè)置分到物理頁的數(shù)目,設(shè)置進(jìn)程的頁面引用情況,可以從鍵盤輸入頁面序列,也可從文件中讀取; ③.隨時計算當(dāng)前的頁面調(diào)度次數(shù)的缺頁中斷率; ④.使用敲鍵盤或響應(yīng)WM-TIMER的形式模仿時間的流逝; ⑤.以直觀的的形式將程序的執(zhí)行情況顯示在計算機(jī)屏幕上; ⑥.存盤及讀盤功能,可以隨時將數(shù)據(jù)存入磁盤文件,供以后重復(fù)實驗時使用。 (2)假定進(jìn)程分配到3個物理塊,對于下面的頁面引用序列:(test.txt) 7-0-1-2-0-3-0-4-2-3-0-3-2-1-2-0-1-7-0-1 請分別用先進(jìn)和先出調(diào)度算法,最近最少用調(diào)度算法,最近最不常用調(diào)度算法計算缺頁中斷次數(shù),缺頁中斷率和缺頁調(diào)度次數(shù)、缺頁置換率。 再假定進(jìn)程分配到4、5個物理塊,重復(fù)本實驗。 (3)假定進(jìn)程分配到3個物理塊,對于下面的頁面引用序列:(test2.txt) 4-3-2-1-4-3-5-4-3-2-1-5-0-7-3-8-9-0-2-1-4-7-3-9 請分別用先進(jìn)先出調(diào)度算法、最近最少用調(diào)度算法,最近最不常用調(diào)度算法計算缺頁中斷次數(shù),缺頁中斷率和缺頁調(diào)度次數(shù)、缺頁置換率。 再假定進(jìn)程分配到4、5個物理塊,重復(fù)本實驗。 (4)假定進(jìn)程分配到3個物理塊,使用程序的動態(tài)頁面序列生成算法,生成一個頁面序列,將此序列存入磁盤文件。再從磁盤文件讀入該序列,用程序分別計算三種算法下的缺頁中斷次數(shù)、缺頁中斷率和缺頁調(diào)度次數(shù)、缺頁置換率。 湖北民族學(xué)院信息工程學(xué)院11級計算機(jī)專業(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級計算機(jī)專業(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級計算機(jī)專業(yè)操作系統(tǒng)課程設(shè)計 參考文獻(xiàn).........................................................................28 引言 操作系統(tǒng)是最重要的系統(tǒng)軟件,同時也是最活躍的學(xué)科之一。我們通過操作系統(tǒng)可以理解計算機(jī)系統(tǒng)的資源如何組織,操作系統(tǒng)如何有效地管理這些系統(tǒng)資源,用戶如何通過操作系統(tǒng)與計算機(jī)系統(tǒng)打交道。 存儲器是計算機(jī)系統(tǒng)的重要組成部分,近年來,存儲器容量雖然一直在不斷擴(kuò)大,但仍不能滿足現(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ù)進(jìn)程的實際需要,動態(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)生,當(dāng)碎片產(chǎn)生時,進(jìn)行碎片的拼接等相關(guān)的內(nèi)容 概要設(shè)計 本程序采用機(jī)構(gòu)化模塊化的設(shè)計方法,共分為四大模塊。⑴最先適應(yīng)算法實現(xiàn) 從空閑分區(qū)表的第一個表目起查找該表,把最先能夠滿足要求的空閑區(qū)分配給作業(yè),這種方法目的在于減少查找時間。為適應(yīng)這種算法,空閑分區(qū)表(空閑區(qū)鏈)中的空閑分區(qū)要按地址由低到高進(jìn)行排序。該算法優(yōu)先使用低址部分空閑區(qū),在低址空間造成許多小的空閑區(qū),在高地址空間保留大的空閑區(qū)。⑵下次適應(yīng)分配算法實現(xiàn) 湖北民族學(xué)院信息工程學(xué)院11級計算機(jī)專業(yè)操作系統(tǒng)課程設(shè)計 該算法是最先適應(yīng)算法的變種。在分配內(nèi)存空間時,不再每次從表頭(鏈?zhǔn)祝╅_始查找,而是從上次找到空閑區(qū)的下一個空閑開始查找,直到找到第一個能滿足要求的的空閑區(qū)為止,并從中劃出一塊與請求大小相等的內(nèi)存空間分配給作業(yè)。該算法能使內(nèi)存中的空閑區(qū)分布得較均勻。⑶最優(yōu)適應(yīng)算法實現(xiàn) 它從全部空閑區(qū)中找出能滿足作業(yè)要求的、且大小最小的空閑分區(qū),這種方法能使碎片盡量小。為適應(yīng)此算法,空閑分區(qū)表(空閑區(qū)鏈)中的空閑分區(qū)要按從小到大進(jìn)行排序,自表頭開始查找到第一個滿足要求的自由分區(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)存管理,是指軟件運(yùn)行時對計算機(jī)內(nèi)存資源的分配和使用的技術(shù)。其最主要的目的是如何高效,快速的分配,并且在適當(dāng)?shù)臅r候釋放和回收內(nèi)存資源。內(nèi)存不是預(yù)先劃分好的,而是在系統(tǒng)運(yùn)行的過程中建立分區(qū).當(dāng)作業(yè)裝入主存時,根據(jù)作業(yè)所需要的主存容量查看是否有足夠的主存空間,若有則按需要分割一個分區(qū)給該作業(yè);否則令該作業(yè)等待.分區(qū)長度不固定分區(qū)個數(shù)不固定。這種存儲管理的方法克服了固定分區(qū)嚴(yán)重浪費(fèi)主存的問題,提高了主存資源的利用率。 內(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)存進(jìn)行移動,甚至刪除。因此,我們在 Windows 應(yīng)用程序中使用內(nèi)存時,要遵循Windows 內(nèi)存管理的一些約定,以盡量提高 Windows 內(nèi)存的利用率。湖北民族學(xué)院信息工程學(xué)院11級計算機(jī)專業(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ù)段,并保證他們在運(yùn)行中的效率以及可靠性,對于每個用戶層(user-level)的進(jìn)程分配一段虛擬內(nèi)存空間。當(dāng)進(jìn)程建立時,不需要在物理內(nèi)存件之間搬移數(shù)據(jù),數(shù)據(jù)儲存于磁盤內(nèi)的虛擬內(nèi)存空間,也不需要為該進(jìn)程去配置主內(nèi)存空間,只有當(dāng)該進(jìn)程被被調(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ū)的劃分由計算機(jī)的操作員或者由操作系統(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)運(yùn)行的過程中建立分區(qū).當(dāng)作業(yè)裝入主存時,根據(jù)作業(yè)所需要的主存容量查看是否有足夠的主存空間,若有則按需要分割一個分區(qū)給該作業(yè);否則令該作業(yè)等待。分區(qū)長度不固定分區(qū)個數(shù)不固定。這種存儲管理的方法克服了固定分區(qū)嚴(yán)重浪費(fèi)主存的問題,提高了主存資源的利用率。IBM操作系統(tǒng)OS/MVT采用可變分區(qū)存儲管理。湖北民族學(xué)院信息工程學(xué)院11級計算機(jī)專業(yè)操作系統(tǒng)課程設(shè)計 可重定位分區(qū)存儲管理 解決碎片問題的一種簡單方法是采用可重定位分區(qū)分配.。其中心思想是,把不同程序,且在內(nèi)存中地址不連續(xù)的想法讓他們連續(xù)。 例:內(nèi)存中現(xiàn)有 3 個空閑區(qū),現(xiàn)有一作業(yè)到達(dá),要求獲得 30k 內(nèi)存空間,沒有分區(qū)滿足容量要求,若想把作業(yè)裝入,可將內(nèi)存中所有作業(yè)進(jìn)行移動,這樣把原來分散的空閑區(qū)匯集成一個大的空閑區(qū)。將內(nèi)存中的作業(yè)進(jìn)行移動使它們連接在一起把原來分散的多個小分區(qū)拼接成一個大的空閑區(qū).這個過程稱為”緊湊”或”移動”。需解決的問題:每次”緊湊”后程序或數(shù)據(jù)裝入的物理地址變化采用動態(tài)重定位。 問題描述和分析 系統(tǒng)應(yīng)利用某種分配算法,從空閑分區(qū)鏈表中找到所需大小的分區(qū),如果空閑分區(qū)大小大于請求分區(qū)大小,則從該分區(qū)中按改請求的大小劃分出一塊內(nèi)存空間大小劃分出一塊內(nèi)存空間分配出去,余下的部分仍留在空閑鏈表中。然后,將分配區(qū)的首址返回給調(diào)用者。 當(dāng)進(jìn)程運(yùn)行完畢師范內(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級計算機(jī)專業(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級計算機(jī)專業(yè)操作系統(tǒng)課程設(shè)計 開始判斷空閑區(qū)上下內(nèi)存情況上為空下為空上下都為空上下都不為空將上面的空閑區(qū)合并,并回收將下面的空閑區(qū)合并,并回收將上下的空閑區(qū)合并,并回收直接將其回收結(jié)束 數(shù)據(jù)結(jié)構(gòu)體分析 ⑴進(jìn)程屬性結(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級計算機(jī)專業(yè)操作系統(tǒng)課程設(shè)計 busyspace * next;}busyspace,*busy 主要程序代碼分析 ⑴主函數(shù)//代碼請?zhí)砑舆m當(dāng)?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.輸入進(jìn)程分配空間...........................n”); printf(“.........................2.進(jìn)程撤銷回收空間...........................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級計算機(jī)專業(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ū)按地址從小到大的次序排列。 分配:當(dāng)進(jìn)程申請大小為 SIZE 的內(nèi)存時,系統(tǒng)順序查找空閑區(qū)表(鏈),直到找到容量滿足要求(≥SIZE)的空閑區(qū)為止。從該空閑區(qū)中劃出大小為 SIZE的分區(qū)分配給進(jìn)程,余下的部分仍作為一個空閑區(qū),但要修改其首址和大小。湖北民族學(xué)院信息工程學(xué)院11級計算機(jī)專業(yè)操作系統(tǒng)課程設(shè)計 優(yōu)點:這種算法是盡可能地利用低地址部分的空閑區(qū),而盡量地保證高地址 6部分的大空閑區(qū),有利于大作業(yè)的裝入。 缺點:主存低地址和高地址分區(qū)利用不均衡。在低地址部分集中了許多非常小的空閑區(qū)碎片降低了主存的利用率。最先適應(yīng)算法 int FF(){ int t=0;readyque D;printf““請輸入進(jìn)程名:””);scanf““%””,D.name); printf““輸入進(jìn)程申請空間大小:””);scanf““%””,&D.size); idly l=Is;int mt=256;busy b=Bs;idly min=NULL;while(l) //尋找空閑表中大小滿足申請進(jìn)程所需大小并且起址最小的空閑結(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ìn)程分配空間 湖北民族學(xué)院信息工程學(xué)院11級計算機(jī)專業(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““請輸入進(jìn)程名:””);scanf““%””,D.name); 湖北民族學(xué)院信息工程學(xué)院11級計算機(jī)專業(yè)操作系統(tǒng)課程設(shè)計 printf““輸入進(jìn)程申請空間大小:””);scanf““%””,&D.size); int mt=256;idly l=Is2;idly min=NULL;busy b=Bs;while(l)//尋找空閑表中大小滿足申請進(jìn)程所需大小并且起址最小的空閑結(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; //如果找到則為進(jìn)程分配空間 湖北民族學(xué)院信息工程學(xué)院11級計算機(jī)專業(yè)操作系統(tǒng)課程設(shè)計 } //將申請空間進(jìn)程插入到已分配鏈表中 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級計算機(jī)專業(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ū)按容量遞增的次序排列。 分配:當(dāng)進(jìn)程申請存儲空間,系統(tǒng)順序查找空閑區(qū)表(鏈),直到找到第一個滿足容量要求的空閑區(qū)為止。采用最優(yōu)適應(yīng)算法選中的空閑區(qū)是滿足容量要求的最小空閑區(qū)。優(yōu)點:選中的空閑區(qū)是滿足容量要求的最小空閑區(qū),而不致于毀掉較大的空閑區(qū)。 缺點:空閑區(qū)的大小一般與申請分區(qū)大小不相等,因此將其一分為二,留下來的空閑區(qū)一般情況下是很小的,以致無法使用。隨著時間的推移,系統(tǒng)中的小空閑區(qū)會越來越多,從而造成存儲空間的浪費(fèi)。最優(yōu)適應(yīng)算法 int BF(){ int t=0;湖北民族學(xué)院信息工程學(xué)院11級計算機(jī)專業(yè)操作系統(tǒng)課程設(shè)計 readyque D;printf““請輸入進(jìn)程名:””);scanf““%””,D.name); printf““輸入進(jìn)程申請空間大小:””);scanf““%””,&D.size); idly l=Is;idly min=NULL;int mt=256;busy b=Bs;while(l)//在空閑鏈中尋找第一個大于所輸入的進(jìn)程大小的空閑塊 { 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; //申請分配用于存放進(jìn)程的內(nèi)存 //找到第一個滿足要求的空閑塊 //將第一個滿足要求的空閑塊(min)的首地址賦給j for(int i=0;i<10;i++) { j->r.name[i]=D.name[i];16 湖北民族學(xué)院信息工程學(xué)院11級計算機(jī)專業(yè)操作系統(tǒng)課程設(shè)計 } j->r.size=D.size; while(b->next) //按從小到大的順序查找新進(jìn)程在已分配區(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ū)按容量遞減的順序排列。 分配:進(jìn)程申請存儲區(qū)時,檢查空閑區(qū)表(鏈)的第一個空閑區(qū)的大小是否滿足要求,若不滿足則令進(jìn)程等待;若滿足則從該空閑區(qū)中分配一部分存儲區(qū)給用戶,剩下的部分仍作為空閑區(qū)。最壞適應(yīng)算法 int WF(){ int t=0;readyque D;printf““請輸入進(jìn)程名:””);scanf““%””,D.name); printf““輸入進(jìn)程申請空間大小:””); //將所輸入的進(jìn)程插入進(jìn)程鏈 //改變該空閑塊的起始地址 //改變該空閑塊的剩余大小 湖北民族學(xué)院信息工程學(xué)院11級計算機(jī)專業(yè)操作系統(tǒng)課程設(shè)計 scanf““%””,&D.size); //輸入進(jìn)程申請的空間大小 idly l=Is;//l指向空閑鏈表ls頭 idly min=NULL;int mt=0;busy b=Bs; //b指向已分配鏈表Bs頭 //找到空閑分區(qū)中大小滿足進(jìn)程的請求且尺寸最大的結(jié)點 while(l){ if(D.size<=l->size)//判斷進(jìn)程所申請的大小是否小于空閑區(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級計算機(jī)專業(yè)操作系統(tǒng)課程設(shè)計 while(b->next)置 //尋找插入到已分配鏈表中的位 { if(b->next->from b=b->next;else break; } //把此進(jìn)程結(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ū)的回收 當(dāng)某個進(jìn)程釋放某存儲區(qū)時,系統(tǒng)首先檢查釋放區(qū)是否與系統(tǒng)中的空閑區(qū)相鄰若相鄰則把釋放區(qū)合并到相鄰的空閑區(qū)去,否則把釋放區(qū)作為一個空閑區(qū)插入到空閑表的適當(dāng)位置。 釋放區(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ū)表的適當(dāng)位置。 湖北民族學(xué)院信息工程學(xué)院11級計算機(jī)專業(yè)操作系統(tǒng)課程設(shè)計 回收內(nèi)存算法 int recover(){ readyque D;printf““請輸入想要回收的進(jìn)程名””); 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; //查找輸入的進(jìn)程名是否在已分配湖北民族學(xué)院信息工程學(xué)院11級計算機(jī)專業(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) //所回收進(jìn)程與空閑結(jié)點上鄰接 { //所回收進(jìn)程與空閑結(jié)點上下都不鄰接 //所回收進(jìn)程與空閑結(jié)點下鄰接 { //所回收進(jìn)程與空閑結(jié)點上下都 21 湖北民族學(xué)院信息工程學(xué)院11級計算機(jī)專業(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; } //從已分配鏈表中釋放所回收進(jìn)程 busy tb=b->next; b->next=b->next->next; free(tb); return 1; } b=b->next;} printf(“沒找到這”進(jìn)程n”);return 0;} //所回收進(jìn)程與空閑結(jié)點上下都鄰調(diào)試與操作說明 初始界面 程序初始界面,有四個塊選擇,選擇要執(zhí)行的算法,調(diào)試以最壞算法為例,如圖 湖北民族學(xué)院信息工程學(xué)院11級計算機(jī)專業(yè)操作系統(tǒng)課程設(shè)計 選擇最壞適應(yīng)算法,如圖 模擬內(nèi)存分配 給進(jìn)程a分配內(nèi)存20,如圖 湖北民族學(xué)院信息工程學(xué)院11級計算機(jī)專業(yè)操作系統(tǒng)課程設(shè)計 已分配分區(qū)說明表界面 同理,給進(jìn)程b分配內(nèi)存30,給進(jìn)程c分配內(nèi)存40,給進(jìn)程d分配50,給進(jìn)程e分配60,如圖 空閑分區(qū)說明表界面 湖北民族學(xué)院信息工程學(xué)院11級計算機(jī)專業(yè)操作系統(tǒng)課程設(shè)計 查看空閑分區(qū),如圖 回收內(nèi)存界面 回收進(jìn)程b和d所占內(nèi)存,如圖 已分配分區(qū)說明表和空閑分區(qū)說明表 如圖 湖北民族學(xué)院信息工程學(xué)院11級計算機(jī)專業(yè)操作系統(tǒng)課程設(shè)計 重新申請內(nèi)存界面 再為新進(jìn)程i分配內(nèi)存30,如圖 湖北民族學(xué)院信息工程學(xué)院11級計算機(jī)專業(yè)操作系統(tǒng)課程設(shè)計 根據(jù)最壞適應(yīng)算法結(jié)合圖所示可知,該算法將會從空閑分區(qū)表中選擇一塊最大的內(nèi)存空間分配給進(jìn)程i,從圖也可看出該模擬算法實現(xiàn)了最壞適應(yīng)算法 湖北民族學(xué)院信息工程學(xué)院11級計算機(jī)專業(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)存管理的機(jī)制實現(xiàn),從而更深一步的的對計算機(jī) 有了很多了解,這對于以后我們的研究和學(xué)習(xí)計算機(jī)系統(tǒng)起到了很重要的作用。 對于本次論文制作,自己的編程能力有所提高,對操作系統(tǒng)內(nèi)存分配,存儲空間的回收都有全新的認(rèn)識。 在這次操作系統(tǒng)課程設(shè)計中,我使用了c++編寫系統(tǒng)軟件,對os中可變分區(qū)存儲管理有了深刻的理解,但是過程中遇到了很多困難,一邊做一邊學(xué),對c++有了比較多的理解。 實驗中遇到很多問題,浪費(fèi)了很多時間,總而言之是自己學(xué)習(xí)還不夠好,不扎實,希望在以后學(xué)習(xí)中加以改善,學(xué)到更多知識。 參考文獻(xiàn) 【1】 湯子瀛,哲鳳屏,湯小丹.計算機(jī)操作系統(tǒng).西安:西安電子科技大學(xué)出版社,2001.。湖北民族學(xué)院信息工程學(xué)院11級計算機(jī)專業(yè)操作系統(tǒng)課程設(shè)計 【2】 任愛華.操作系統(tǒng)實用教程.北京:清華大學(xué)出版社,2001。 長春理工大學(xué) 軟件學(xué)院 0813111班 27號 姓名:丁為勝 一. 概述 1、課程設(shè)計目的及任務(wù)課程設(shè)計地點及要求 每個學(xué)生一臺微機(jī),需要安裝windows98或windows2000操作系統(tǒng),配備VC、VB、java或C編程語言,每個學(xué)生上機(jī)時間不少于24個小時。 操作系統(tǒng)是計算機(jī)專業(yè)的核心專業(yè)課,“操作系統(tǒng)課程設(shè)計”是理解和鞏固操作系統(tǒng)基本理論、原理和方法的重要的實踐環(huán)節(jié)。 操作系統(tǒng)課程主要講述的內(nèi)容是多道操作系統(tǒng)的原理與技術(shù),與其它計算機(jī)原理、編譯原理、匯編語言、計算機(jī)網(wǎng)絡(luò)、程序設(shè)計等專業(yè)課程關(guān)系十分密切。本課程設(shè)計的目的綜合應(yīng)用學(xué)生所學(xué)知識,建立系統(tǒng)和完整的計算機(jī)系統(tǒng)概念,理解和鞏固操作系統(tǒng)基本理論、原理和方法,掌握操作系統(tǒng)基本理論與管理方式。在算法基礎(chǔ)上,解決實際的管理功能的問題,提高學(xué)生實際應(yīng)用、編程的能力。 主要任務(wù)是實現(xiàn)操作系統(tǒng)和相關(guān)系統(tǒng)軟件的設(shè)計,其中涉及進(jìn)程創(chuàng)建,同步,進(jìn)程間的通信,存儲管理,文件系統(tǒng)等操作系統(tǒng)概念。 2.課程設(shè)計地點及要求 每個學(xué)生一臺微機(jī),需要安裝windows98或windows2000操作系統(tǒng),配備VC、VB、java或C編程語言,每個學(xué)生上機(jī)時間不少于24個小時。 3.課程設(shè)計的內(nèi)容 設(shè)計二: 設(shè)計任務(wù): 掌握進(jìn)程的管道通訊機(jī)制和信號量同步互斥機(jī)制。1. 進(jìn)程的管道通訊 編制一個程序,程序中創(chuàng)建一個子進(jìn)程。然后父子進(jìn)程各自獨立運(yùn)行,父進(jìn)程不斷地在標(biāo)準(zhǔn)輸入設(shè)備上讀入小寫字母,寫入管道。子進(jìn)程不斷地從管道中讀取字符,轉(zhuǎn)換為大寫字母后輸出到標(biāo)準(zhǔn)輸出設(shè)備上。當(dāng)讀到x時,結(jié)束。 2. 信號量實現(xiàn)的同步互斥機(jī)制 編制一個程序,程序中創(chuàng)建5個子進(jìn)程,代表五位哲學(xué)家,然后父進(jìn)程結(jié)束。使用信號量機(jī)制解決哲學(xué)家進(jìn)餐問題。當(dāng)哲學(xué)家進(jìn)餐時,屏幕輸出: [進(jìn)程號] eating!當(dāng)哲學(xué)家思考時,屏幕輸出: [進(jìn)程號] 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.進(jìn)程的管道通訊 管道(Pipe)實際是用于進(jìn)程間通信的一段共享內(nèi)存,創(chuàng)建管道的進(jìn)程稱為管道服務(wù)器,連接到一個管道的進(jìn)程為管道客戶機(jī)。命名管道(Named Pipes)是在管道服務(wù)器和一臺或多臺管道客戶機(jī)之間進(jìn)行單向或雙向通信的一種命名的管道。一個命名管道的所有實例共享同一個管道名,但是每一個實例均擁有獨立的緩存與句柄,并且為客戶——服務(wù)通信提供有一個分離的管道。實例的使用保證了多個管道客戶能夠在同一時間使用同一個命名管道。 2.信號量實現(xiàn)的同步互斥機(jī)制 規(guī)定奇數(shù)號的哲學(xué)家先拿起他左邊的筷子,然后再去拿他右邊的筷子;而偶數(shù)號 的哲學(xué)家則相反.按此規(guī)定,將是1,2號哲學(xué)家競爭1號筷子,3,4號哲學(xué)家競爭3號筷子.即 五個哲學(xué)家都競爭奇數(shù)號筷子,獲得后,再去競爭偶數(shù)號筷子,最后總會有一個哲學(xué)家能獲 得兩支筷子而進(jìn)餐。而申請不到的哲學(xué)家進(jìn)入阻塞等待隊列,根FIFO原則,則先申請的哲 學(xué)家會較先可以吃飯,因此不會出現(xiàn)餓死的哲學(xué)家。 三. 總體設(shè)計 1.實現(xiàn)的方法和主要技術(shù)路線 1.無名管道 無名管道用于具有親緣關(guān)系的父子進(jìn)程,子子進(jìn)程之間的通訊。它的實現(xiàn)函數(shù)有 int pipe(int fd[2]); //fd[2] 為描述符數(shù)組,包含一個讀描述符與一個寫描述符,在使用管道通信時,關(guān)閉某些不需要的讀或?qū)懨枋龇?,建立起單向的讀或?qū)懝艿?,然后用read 和write 像操作文件一樣去操作它即可。 如圖便是進(jìn)程1 到進(jìn)程2 的一個讀管道。 分別在父進(jìn)程和父子進(jìn)程里向管道寫數(shù)據(jù),然后在子進(jìn)程和子子進(jìn)程里讀數(shù)據(jù)。2.哲學(xué)家進(jìn)餐偽碼: 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);} } 四. 詳細(xì)設(shè)計 進(jìn)程的管道通信代碼: 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(“子進(jìn)程讀取的字符為:”+str.toUpperCase()); if(!str.endsWith(“x”)) { System.out.print(“父進(jìn)程讀入字符為:”); }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(“父進(jìn)程讀入字符為:”);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é)家進(jìn)餐問題代碼: #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é)家開始進(jìn)餐 { eattime=ineattime; *left=false; *right=false;} bool finish()//檢查哲學(xué)家是否完成進(jìn)餐 { 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é)家進(jìn)餐問題”);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é)家進(jìn)餐隊列:”< 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è)計
第五篇:操作系統(tǒng)課程設(shè)計