存儲管理實驗
❶ 操作系統存儲管理實驗
#include<stdio.h>#include <dos.h>#include<stdlib.h>#include<conio.h>#include<iostream.h>
#define n 10 /*假定系統允許的最大作業數為n,假定模擬實驗中n值為10*/ #define m 10 /*假定系統允許的空閑區表最大為m,假定模擬實驗中m值為10*/ #define minisize 100 /*空閑分區被分配時,如果分配後剩餘的空間小於minisize,則將該空閑分區全部分配,若大於minisize,則切割分配*/
struct { float address; /*已分配分區起始地址*/ float length; /*已分配分區長度,單位為位元組*/ int flag; /*已分配區表登記欄標志,用"0"表示空欄目*/ }used_table[n]; /*已分配區表*/
struct { float address; /*空閑區起始地址*/ float length; /*空閑區長度,單位為位元組*/ int flag; /*空閑區表登記欄標志,用"0"表示空欄目,用"1"表示未分配*/ }free_table[m]; /*空閑區表*/
void allocate(char J,float xk) /*給J作業,採用最佳分配演算法分配xk大小的空間*/ { int i,k; float ad; k=-1;
for(i=0;i<m;i++) /*尋找空間大於xk的最小空閑區登記項k*/ if(free_table[i].length>=xk&&free_table[i].flag==1) if(k==-1||free_table[i].length<free_table[k].length) k=i; if(k==-1)/*未找到可用空閑區,返回*/ { printf("無可用空閑區\n"); return; }
/*找到可用空閑區,開始分配:若空閑區大小與要求分配的空間差小於minisize大小,則空閑區全部分配;若空閑區大小與要求分配的空間差大於minisize大小,則從空閑區劃出一部分分配*/ if(free_table[k].length-xk<=minisize) { free_table[k].flag=0; ad=free_table[k].address; xk=free_table[k].length; } else { free_table[k].length=free_table[k].length-xk; ad=free_table[k].address+free_table[k].length; } /*修改已分配區表*/ i=0; while(used_table[i].flag!=0&&i<n) /*尋找空表目*/ i++;
if(i>=n) /*無表目可填寫已分配分區*/ { printf("無表目填寫已分分區,錯誤\n");
/*修正空閑區表*/ if(free_table[k].flag==0) /*前面找到的是整個空閑分區*/ free_table[k].flag=1; else {/*前面找到的是某個空閑分區的一部分*/ free_table[k].length=free_table[k].length+xk; return; } } else {/*修改已分配表*/ used_table[i].address=ad; used_table[i].length=xk; used_table[i].flag=J; }
return; }/*主存分配函數結束*/
void reclaim(char J) /*回收作業名為J的作業所佔主存空間*/ { int i,k,j,s,t; float S,L;
/*尋找已分配表中對應登記項*/ s=0; while((used_table[s].flag!=J||used_table[s].flag==0)&&s<n) s++;
if(s>=n)/*在已分配表中找不到名字為J的作業*/ { printf("找不到該作業\n"); return; }
/*修改已分配表*/ used_table[s].flag=0;
/*取得歸還分區的起始地址S和長度L*/ S=used_table[s].address; L=used_table[s].length; j=-1;k=-1;i=0;
/*尋找回收分區的空閑上下鄰,上鄰表目k,下鄰表目j*/ while(i<m&&(j==-1||k==-1)) { if(free_table[i].flag==1) { if(free_table[i].address+free_table[i].length==S)k=i;/*找到上鄰*/ if(free_table[i].address==S+L)j=i;/*找到下鄰*/ } i++; }
if(k!=-1) if(j!=-1) /* 上鄰空閑區,下鄰空閑區,三項合並*/ { free_table[k].length=free_table[j].length+free_table[k].length+L; free_table[j].flag=0; } else /*上鄰空閑區,下鄰非空閑區,與上鄰合並*/ free_table[k].length=free_table[k].length+L; else if(j!=-1) /*上鄰非空閑區,下鄰為空閑區,與下鄰合並*/ { free_table[j].address=S; free_table[j].length=free_table[j].length+L; } else /*上下鄰均為非空閑區,回收區域直接填入*/ { /*在空閑區表中尋找空欄目*/ t=0; while(free_table[t].flag==1&&t<m) t++; if(t>=m)/*空閑區表滿,回收空間失敗,將已分配表復原*/ { printf("主存空閑表沒有空間,回收空間失敗\n"); used_table[s].flag=J; return; } free_table[t].address=S; free_table[t].length=L; free_table[t].flag=1; } return; }/*主存回收函數結束*/
int main( ) { int i,a; float xk; char J;
/*空閑分區表初始化:*/ free_table[0].address=10240; /*起始地址假定為10240*/ free_table[0].length=10240; /*長度假定為10240,即10k*/ free_table[0].flag=1; /*初始空閑區為一個整體空閑區*/ for(i=1;i<m;i++) free_table[i].flag=0; /*其餘空閑分區表項未被使用*/
/*已分配表初始化:*/ for(i=0;i<n;i++) used_table[i].flag=0; /*初始時均未分配*/
while(1) { printf("選擇功能項(0-退出,1-分配主存,2-回收主存,3-顯示主存)\n"); printf("選擇功項(0~3) :");
scanf("%d",&a); switch(a) { case 0: exit(0); /*a=0程序結束*/
case 1: /*a=1分配主存空間*/ printf("輸入作業名J和作業所需長度xk: "); scanf("%*c%c%f",&J,&xk); allocate(J,xk); /*分配主存空間*/ break;
case 2: /*a=2回收主存空間*/ printf("輸入要回收分區的作業名"); scanf("%*c%c",&J); reclaim(J); /*回收主存空間*/ break;
case 3: /*a=3顯示主存情況*/ /*輸出空閑區表和已分配表的內容*/ printf("輸出空閑區表:\n起始地址 分區長度 標志\n"); for(i=0;i<m;i++) printf("%6.0f%9.0f%6d\n",free_table[i].address,free_table[i].length, free_table[i].flag); printf(" 按任意鍵,輸出已分配區表\n"); getch(); printf(" 輸出已分配區表:\n起始地址 分區長度 標志\n"); for(i=0;i<n;i++) if(used_table[i].flag!=0) printf("%6.0f%9.0f%6c\n",used_table[i].address,used_table[i].length, used_table[i].flag); else printf("%6.0f%9.0f%6d\n",used_table[i].address,used_table[i].length, used_table[i].flag); break;
default:printf("沒有該選項\n"); }/*case*/ }/*while*/
return 1;}
❷ 操作系統:實驗五 內存分區管理實驗
實驗五 內存分區管理實驗
一、單項選擇題(共5題,每題10分,共50分)
1、最佳適應演算法的空白區是__B__。
A.按大小遞減順序連在一起 B.按大小遞增順序連在一起
C.按地址由小到大排列 D.按地址由大到小排序
2、在固定分區分配中,每個分區的大小是__C__。
A. 相同 B.隨作業長度變化
C.可以不同但預先固定 D.可以不同但根據作業長度固定
3、採用__B__不會產生內部碎片。
A. 分頁式存儲管理 B.分段式存儲管理
C. 固定分區式存儲管理 D.段頁式存儲管理
4、在可變式分區存儲管理中的拼接技術可以_A___。 A.集中空閑區 B.增加內存容量
C.縮短訪問周期 D.加速地址轉換
5、採用分段存儲管理的系統中,若地址用24位表示,其中8位表示段號,則允許每段的最大長度是_B___。
二、填空題(共4題,每題5分,共20分)
1、在分區分配演算法中,首次適應演算法傾向於優先利用內存中的_低地址___部分的空閑分區,從而保留了__高地址__部分的大空閑區。
2、在可變分區存儲管理中,分區的保護通常採用_地址越界___和__非法操作__兩種方法。
3、3、採用交換技術獲得的好處是以犧牲_增大系統開銷___為代價的。
4、在採用請求分頁式存儲管理的系統中,地址變換過程可能會因為_缺頁___、_越界___和_訪問許可權錯誤___等原因而產生中斷。
三、 簡答題(共2題,每題15分,共30分) 1、可採用哪幾種方式將程序裝入內存?它們分別適用於何種場合?
a. 首先由編譯程序將用戶源代碼編譯成若干目標模塊,再由鏈接程序將編譯後形成的目標模塊和所需的
---庫函數鏈接在一起,組成一個裝入模塊,再由裝入程序將裝入模塊裝入內存;
b. 裝入模塊的方式有: 絕對裝入方式,可重定位方式和動態運行時裝入方式;
c. 絕對裝入方式適用於單道程序環境下;
d. 可重定位方式適用於多道程序環境下;
e. 動態運行時裝入方式也適用於多道程序環境下.
2、何謂靜態鏈接?何謂裝入時動態鏈接和運行時的動態鏈接?
a. 靜態鏈接是指事先進行鏈接形成一個完整的裝入模塊,以後不再拆開的鏈接方---式;
b. 裝入時動態鏈接是指目標模塊在裝入內存時,邊裝入邊鏈接的鏈接方式;
c. 運行時的動態鏈接是將某些目標模塊的鏈接推遲到執行時才進行.
❸ 操作系統:請求頁式存儲管理中頁面置換演算法的模擬設計
srand()——獲取運算隨機數(數據類型:double);
getpid()——獲取當前進程識別碼(long);
srand(10*getpid())就是產生一個10陪的隨機數。該隨機函數的種子參數是getpid(),少了10意義就不一樣了,所以不行
s=(float)319*rand()/32767/32767/2+1,是一個算術式,rand()函數是產生隨機數的一個隨機函數,float是一種數據類型,為浮點數,S就是一個隨機數乘以319除以32767/32767/2+1的值,32767是2的(16-1)次方,為什麼要減1,因為是從0開始,0到15,2的0次方是1,一直算下去,2的(16-1)次方是32767,把(float)319*rand()/32767/32767/2+1所得的值存儲在S變數里
希望採納
❹ 求用c++程序設計的實驗:模擬分頁式存儲管理中硬體的地址轉換和用先進先出調度演算法(FIFO)處理缺頁中斷。
#include<iostream.h>
#include<stdlib.h>
#include<iomanip.h>
#include"windows.h"
#include"os.h"
#define n 64//實驗中假定主存的長度
#define m 4//實驗中假定每個作業分得主存塊塊數
int p[m];//定義頁
struct
{
short int lnumber;//頁號
short int flag;//表示該頁是否在主存,「1」表示在主存,「0」表示不在主存
short int pnumber;//該頁所在主存塊的塊號
short int write;//該頁是否被修改過,「1」表示修改過,「0」表示沒有修改過
short int dnumber;//該頁存放在磁碟上的位置,即磁碟塊號
short int times;//被訪問的次數,用於LRU演算法
}page[n];//定義頁表
//各個函數的實現如下:
computer::computer()
{
int i;
for(i=0;i<n;i++)
{
page[i].lnumber = i;
page[i].flag = 0;
page[i].pnumber = 10000;//用10000表示為空
page[i].write = 0;
page[i].dnumber = i;
page[i].times = 0;
}//初始化頁表
for(i=0;i<m;i++)
{
page[i].pnumber = i;
}
for(i=0;i<m;i++)
{
p[i] = i;
page[i].flag = 1;
}//初始化頁
}
void computer::showpagelist()
{
int i;
cout<<"頁號"<<"\t"<<"是否在主存中"<<"\t"<<"塊 號"<<"\t"<<"是否被修改過"<<"\t"<<"磁碟塊號"<<"\t"<<"訪問次數"<<endl;
for(i=0;i<n;i++)
{
cout<<page[i].lnumber<<"\t"<<page[i].flag<<" "<<page[i].pnumber<<"\t"<<page[i].write<<" "<<page[i].dnumber<<" \t"<<page[i].times<<endl;
}
}
void computer::showpage()
{
int i;
for(i=0;i<m;i++)
{
cout<<"\t"<<p[i];
}
cout<<endl;
}
void computer::transformation()
{
unsigned logicAddress,logicNumber,innerAddress,physicsAddress,physicsNumber;
int i,head=0,fail = 0;
int method,temppage=0;
short int times = 10000;
cout<<"請輸入一個邏輯地址(四位十六進制數):";
cin>>hex>>logicAddress;//讀入邏輯地址
logicNumber = logicAddress >> 10;//得到頁號
cout<<"頁號為:"<<logicNumber<<endl;
innerAddress = logicAddress & 0x03ff;//得到頁內地址
cout<<"頁內地址為:"<<innerAddress<<endl;
for(i=0;i<n;i++)
{
if(logicNumber==(unsigned)page[i].lnumber)
{
if(page[i].flag == 1)
{
cout<<"請求的頁面在主存中!"<<endl;
page[i].times++;
physicsNumber = page[i].pnumber;//由頁號得到塊號
cout<<"請求的主存塊號為:"<<physicsNumber<<endl;
physicsAddress = physicsNumber << 10 |innerAddress;//得到物理地址
cout<<"請求的物理地址為:"<<physicsAddress<<endl;//輸出物理地址
break;
}
else
{
cout<<"請求的頁面不在主存中! 將進行缺頁中斷處理!"<<endl<<"請選擇演算法!"<<endl;
cout<<"1.先進先出"<<endl<<"2.最近最少用"<<endl<<"請選擇置換演算法:";
cin>>method;
if(method == 1) //採用先進先出演算法
{
cout<<"採用先進先出演算法!"<<endl;
fail = p[head];
cout<<"第"<<fail<<"頁將被替換!"<<endl;
p[head] = logicNumber;
head = (head+1) % m;
if(page[fail].write == 1)
cout<<"第"<<fail<<"頁曾被修改過!"<<endl;
page[fail].flag = 0;
page[logicNumber].flag = 1;
page[logicNumber].write = 0;
page[logicNumber].pnumber = page[fail].pnumber;
page[fail].pnumber = 10000;
page[logicNumber].times++;
break;
}
else if(method == 2) //採用最近最少用演算法
{
cout<<"採用最近最少用演算法!"<<endl;
for(i=0;i<n;i++)
{
if(page[i].flag == 1)
{
if(page[i].times<times)
{
times = page[i].times;
temppage = page[i].lnumber;
}
}
}
cout<<"第"<<temppage<<"頁將被替換!"<<endl;
for(i=0;i<m;i++)
{
if(p[i] == temppage)
{
p[i] = logicNumber;
}
}
if(page[temppage].write == 1)
cout<<"第"<<temppage<<"頁曾被修改過!"<<endl;
page[temppage].flag = 0;
page[logicNumber].flag = 1;
page[logicNumber].write = 0;
page[logicNumber].pnumber = page[temppage].pnumber;
page[temppage].pnumber = 10000;
page[logicNumber].times++;
break;
}
else
{ cout<<"你輸入有誤,即將退出!";
exit(1);
}
}
}
}
}
void main()
{
char c,d;
computer os;
cout<<"頁表正在初始化中...,3秒鍾後為你顯示頁和頁表!"<<endl;
Sleep(3000);
os.showpage();
os.showpagelist();
T:
os.transformation();
cout<<"是否顯示頁和頁表?(Y/N)";
cin>>c;
switch(c)
{
case 'y':
os.showpage();
os.showpagelist();
case 'n':
cout<<"是否繼續進行請求分頁?(Y/N)";
cin>>d;
if (d=='Y'||d=='y')
goto T;
else if (d=='N'||d=='n')
exit(1);
else
cout<<"輸入錯誤!"<<endl;
default:cout<<"輸入錯誤!"<<endl;
}
}