

1.实现效果


2.实现源代码
1 #include<iostream>
2 #include<process.h>
3 #include<stdlib.h>
4 #include<ctime>
5 #include<conio.h>
6 #include<stdio.h>
7 #include<string.h>
8 using namespace std;
9
10 #define Myprintf printf("|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|
")/*表格控制*/
11 #define bsize 4 //物理块大小
12 #define psize 16 //进程大小
13 void chushihua();//初始化函数
14 void ymzh();
15 void yemianzhihuan ();
16 void changeaddr(struct Page p[], int logaddr);
17 void dizhizhuanhuan();
18 void menu();
19 int wang();
20
21 int yemianliu[32]={0};//全局变量数组,地址流
22 int p;
23 struct Page {
24 int pno;//页号
25 int flag;//标志位
26 int cno;//主存号
27 int modf;//修改位
28 int addr;//外存地址
29 }Page; //全局变量p是一共有多少地址流
30
31 typedef struct pagel
32 {
33 int num; /*记录页面号*/
34 int time; /*记录调入内存时间*/
35 }Pagel; /*页面逻辑结构,方便算法实现*/
36
37 Pagel b[bsize]; /*内存单元数*/
38 int c[bsize][psize];/*保存内存当前的状态:缓冲区*/
39 int queue[100];/*记录调入队列*/
40 int k;/*调入队列计数变量*/
41 int phb[bsize]={0};//物理块标号
42 int pro[psize]={0};//进程序列号
43 int flag[bsize]={0};//进程等待次数(存放最久未被使用的进程标志)*/
44 int i=0,j=0;//i表示进程序列号,j表示物理块号*/
45 int m =-1,n =-1;//物理块空闲和进程是否相同判断标志*/
46 int mmax=-1, maxflag=0;//标记替换物理块进程下标*/
47 int count =0; //统计页面缺页次数
48
49 void chushihua() //初始化函数
50 {
51 int t;
52 srand(time(0));//随机产生指令序列
53 p=12+rand()%32;
54 cout<<"地址流序列:";
55 cout<<endl;
56 for(i=0; i<p; i++)
57 {
58 t=1+rand()%9;
59 yemianliu[i]=t;//将随机产生的指令数存入页面流
60 }
61 for (i=p-1;i>=0;i--)
62 {
63 cout<<yemianliu[i]<<" ";
64 }
65 cout<<endl;
66 }
67 void ymzh()
68 {
69 chushihua();
70 yemianzhihuan();
71 }
72
73 void yemianzhihuan()
74 {
75 int a;
76 printf("----------------------------------
");
77 printf("☆☆欢迎使用分页模拟实验系统☆☆
");
78 printf("----------------------------------");
79 printf("☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
");
80 printf("☆☆1.进入硬件地址变换算法 ☆☆
");
81 printf("☆☆------------------------☆☆
");
82 printf("☆☆2.进入页面置换算法 ☆☆
");
83 printf("☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
");
84 printf("请输入您的选择:");
85 switch(a)
86 {
87 case 1:
88 ymzh();
89 break;
90 case 2:
91 wang();
92 break;
93 default:
94 cout<<"输入有误,请重新输入!"<<endl;
95 break;
96 }
97 }
98
99 void changeaddr(struct Page p[], int logaddr){//地址变换
100 int j=logaddr/64;//对应的块号
101 int k=logaddr%64; //对应的偏移量
102 int flag=0;
103 int addr;
104 for(int i=0;i<8;i++)
105 {
106 if(p[i].pno==j)//找到对应的页号
107 {
108 if(p[i].flag==1)//页面标志为1
109 {
110 addr=p[i].cno*64+k;
111 cout<<"物理地址为:"<<addr<<endl;
112 cout<<"详细信息:"<<" 页面号:"<<p[i].pno<<" 主存号:"<<p[i].cno<<" 偏移量:"<<k<<endl;
113 flag=1;
114 break;
115 }
116 }
117 }
118
119 if(flag==0)
120 cout<<"该页不在主存,产生缺页中断"<<endl;
121 }
122
123 void dizhizhuanhuan()
124 {
125 int a;
126 int ins;//指令逻辑地址
127 struct Page p[8];
128 p[0].pno=0;p[0].flag=1;p[0].cno=5;p[0].modf=1;p[0].addr=011;
129 p[1].pno=1;p[1].flag=1;p[1].cno=8;p[1].modf=1;p[1].addr=012;
130 p[2].pno=2;p[2].flag=1;p[2].cno=9;p[2].modf=0;p[2].addr=013;
131 p[3].pno=3;p[3].flag=1;p[3].cno=10;p[3].modf=0;p[3].addr=015;
132 p[4].pno=4;p[4].flag=0;p[4].addr=017;
133 p[5].pno=5;p[5].flag=0;p[5].addr=025;
134 p[6].pno=6;p[6].flag=0;p[6].addr=212;
135 p[7].pno=7;p[7].flag=0;p[7].addr=213;
136 printf(" --------------------------------
");
137 printf(" ☆☆欢迎使用分页模拟实验系统☆☆
");
138 printf(" ---------------------------------
");
139 printf(" ☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
");
140 printf(" ☆☆1.输入指令 ☆☆
");
141 printf(" ☆☆------------------------☆☆
");
142 printf(" ☆☆2.进入页面置换算法 ☆☆
");
143 printf(" ☆☆------------------------☆☆
");
144 printf(" ☆☆0.EXIT ☆☆
");
145 printf(" ☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
");
146 while(a!=0)
147 {
148 cout<<endl<<"请输入您的选择:";
149 cin>>a;
150
151 cout<<"页号"<<"标记位"<<"外存地址"<<"主存号"<<endl;
152 for(int i=0;i<8;i++)
153 {
154 cout<<p[i].pno<<" "<<p[i].flag<<" "<<p[i].addr<<" ";
155 if(p[i].flag)
156 cout<<p[i].cno;
157 cout<<endl;
158 }
159
160 switch(a)
161 {
162 case 0:printf(" 再见!
"); break;
163 case 1:
164 cout<<"请输入指令的逻辑地址:";
165 cin>>ins;
166 changeaddr(p, ins);break;
167 case 2: system("CLS"); a=wang();break;
168 default:cout<<"输入有误,请重新输入!"<<endl;break;
169 }
170 }
171 }
172
173 void menu()
174 {
175 int a;
176 printf(" --------------------------------
");
177 printf(" ☆☆欢迎使用分页模拟实验系统☆☆
");
178 printf(" ---------------------------------
");
179 printf(" ☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
");
180 printf(" ☆☆1.输入指令 ☆☆
");
181 printf(" ☆☆------------------------☆☆
");
182 printf(" ☆☆2.进入页面置换算法 ☆☆
");
183 printf(" ☆☆------------------------☆☆
");
184 printf(" ☆☆0.EXIT ☆☆
");
185 printf(" ☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
");
186 printf("请选择所要执行的操作:");
187 scanf("%d",&a);
188 switch(a)
189 {
190 case 0: printf(" -再见!-
");break;
191 case 1: dizhizhuanhuan (); break;
192 case 2: wang (); break;
193 default:cout<<"输入有误,请重新输入!"<<endl;break;
194 }
195 }
196 int main()
197 {
198 menu();
199 }
200
201 //****************随机产生序列号函数
202 int* build()
203 {
204 printf("随机产生一个进程序列号为:
");
205 int i=0;
206 for(i=0; i<psize; i++)
207 {
208 pro[i]=10*rand()/(RAND_MAX+1)+1;
209 printf("%d ", pro[i]);
210 }
211 printf("
");
212 return(pro);
213 }
214
215 //***************************************查找空闲物理块
216 int searchpb()
217 {
218 for (j=0;j<bsize; j++)
219 {
220 if(phb[j] == 0)
221 {
222 m=j;
223 return m;
224 break;
225 }
226 }
227 return -1;
228 }
229 //************************************查找相同进程
230 int searchpro()
231 {
232 for(j=0;j< bsize;j++)
233 {
234 if(phb[j] =pro[i])
235 {
236 n=j;
237 return j;
238 }
239 }
240 return -1;
241 }
242
243 //*************************初始化内存
244 void empty()
245 {
246 for(i=0;i<bsize;i++)
247 phb[i]=0;
248 count=0; //计数器置零
249 } //******先进先出页面置换算法
250 void FIFO()
251 {
252 for( i=0; i<psize; i++)
253 {
254 // m=searchpb();
255 // n=searchpro();
256 //找到第一个空闲的物理快
257 for(j=0;j<bsize;j++) {
258 if(phb[j] == 0){
259 m=j;
260 break;
261 }
262 }
263 //找与进程相同的标号
264 for(j=0;j<bsize;j++) {
265 if(phb[j] == pro[i]){
266 n=j;
267 }
268 }
269
270 //找flag值最大的
271 for(j=0;j<bsize;j++)
272 {
273 if(flag[j]>maxflag)
274 {
275 maxflag = flag[j];
276 mmax = j;
277 }
278 }
279
280 if(n == -1)//不存在相同进程
281 {
282 if(m != -1)//存在空闲物理块
283 {
284 phb[m]=pro[i];//进程号填入该空闲物理块
285 // count++;
286 flag[m]=0;
287 for (j=0;j<=m; j++)
288 {
289 flag[j]++;
290 }
291 m=-1;
292 }
293 else//不存在空闲物理块
294 {
295 phb[mmax] =pro[i];
296 flag[mmax] =0;
297 for (j=0;j<bsize;j++)
298 {
299 flag[j]++;
300 }
301 mmax = -1;
302 maxflag = 0;
303 count++;
304 }
305 }
306 else//存在相同的进程
307 {
308 phb[n] = pro[i];
309 for(j=0;j<bsize;j++)
310 {
311 flag[j]++;
312 }
313 n=-1;
314 }
315 for(j=0;j < bsize;j++)
316 {
317 printf("%d ", phb[j]);
318 }
319 printf("
");
320 }
321 printf("缺页次数为:%d
",count);
322 printf("缺页率 :%16. 6f",(float)count/psize);
323 printf("
");
324 }
325 /*初始化内存单元、缓冲区*/
326 void Init(Pagel *b,int c[bsize][psize])
327 {
328 int i,j;
329 for (i=0;i<psize;i++)
330 {
331 b[i].num=-1;
332 b[i].time=psize-i-1;
333 }
334 for(i=0;i<bsize;i++)
335 for(j=0;j<psize;j++)
336 c[i][j]=-1;
337 }
338 /*取得在内存中停留最久的页面,默认状态下为最早调入的页面*/
339 int GetMax(Pagel *b)
340 {
341 int i;
342 int max=-1;
343 int tag=0;
344 for(i=0;i<bsize;i++)
345 {
346 if(b[i].time>max)
347 {
348 max=b[i].time;
349 tag= i;
350 }
351 }
352 return tag;
353 }
354
355 /*判断页面是否已在内存中*/
356 int Equation(int fold, Pagel *b)
357 {
358 int i;
359 for(i=0;i<bsize;i++)
360 {
361 if(fold==b[i]. num)
362 return i;
363 }
364 return -1;
365 }
366 /*LRU核心部分*/
367 void Lruu(int fold, Pagel *b)
368 {
369 int i;
370 int val;
371 val=Equation(fold, b);
372 if (val>=0)
373 {
374 b[val].time=0;
375 for(i=0;i<bsize;i++)
376 if (i!=val)
377 b[i].time++;
378 }
379 else
380 {
381 queue[++k]=fold;/*记录调入页面*/
382 val=GetMax(b);
383 b[val].num=fold;
384 b[val].time=0;
385 for (i=0;i<bsize;i++){
386
387 // URLcount++;
388 if (i!=val)
389 b[i].time++;
390 }
391 }
392 }
393
394 void LRU()
395 {
396 int i,j;
397 k=0;
398 Init(b, c);
399 for(i=0; i<psize; i++)
400 {
401 Lruu(pro[i],b);
402 c[0][i]=pro[i];
403 /*记录当前的内存单元中的页面*/
404 for(j=0;j<bsize;j++)
405 c[j][i]=b[j].num;
406 }
407
408 /*结果输出*/
409 printf("内存状态为:
");
410 Myprintf;
411 for(j=0;j<psize;j++)
412 printf("|%2d", pro[j]);
413 printf("|
");
414 Myprintf;
415
416 for(i=0;i<bsize;i++)
417 {
418 for(j=0; j<psize; j++)
419 {
420 if(c[i][j]==-1)
421 printf("|%2c",32);
422 else
423 printf("|%2d",c[i][j]);
424 }
425 printf("|
");
426 }
427
428 Myprintf;
429 // printf("
调入队列为:");
430 // for(i=0;i<k;i++)
431 // printf("%3d", queue[i]);
432
433 printf("
缺页次数为:%6d
缺页率 :%16. 6f", k+1,(float)(k+1)/psize);
434 }
435
436 //********主函数
437 int wang()
438 {
439 int sel;
440 do{
441 printf(" --------------------------------
");
442 printf(" ☆☆欢迎使用分页模拟实验系统☆☆
");
443 printf(" ---------------------------------
");
444 printf(" ☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
");
445 printf(" ☆☆ 虚拟内存 ☆☆
");
446 printf(" ☆☆------------------------☆☆
");
447 printf(" ☆☆1.产生随机序列 ☆☆
");
448 printf(" ☆☆------------------------☆☆
");
449 printf(" ☆☆2.最近最久未使用 ☆☆
");
450 printf(" ☆☆------------------------☆☆
");
451 printf(" ☆☆3.先进先出 ☆☆
");
452 printf(" ☆☆------------------------☆☆
");
453 printf(" ☆☆0.退出 ☆☆
");
454 printf(" ☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
");
455 printf("请选择所要执行的操作:");
456 scanf("%d",&sel);
457 switch(sel)
458 {
459 case 0: printf(" 再见!t
"); break;
460 case 1: build(); break;
461 case 2: printf("最近最久未使用
"); LRU();empty(); printf("
");break;
462 case 3: printf("先进先出算法
"); FIFO();empty();printf("
");break;
463 default:printf("请输入正确的选项号!");printf("
");break;
464 }
465 }while(sel !=0 );
466 return sel;
467 }