操作系统实验3 请求分页式存储管理
- 格式:docx
- 大小:61.72 KB
- 文档页数:5
实验3 请求分页存储管理实验目的(1)熟悉主存的分配与回收;(2)了解虚拟存储技术的特点;(3)掌握请求页式存储管理的页面置换算法;实验内容与步骤1、实验准备知识(1) 通过随机数产生一个指令序列(2) 将指令序列变换成为页地址流设:(3) 计算并输出下述各种算法在不同内存容量下的命中率a) 先进先出的算法(FIFO);b) 最近最少使用算法(LRU);c) 最佳淘汰算法(OPT);(4)所涉及的算法1)FIFO算法定义变量ptr。
一开始先预调页填满内存。
在这一部分,ptr指向下一个要存放的位置。
之后继续执行剩下的指令。
此时,ptr表示队列最前面的位置,即最先进来的位置,也就是下一个要被替换的位置。
ptr用循环加,即模拟循环队列。
2)LRU算法定义数组ltu[],即last_time_use来记录该页最近被使用的时间。
定义变量ti模拟时间的变化,每执行一次加一。
这个算法,我没有预调页,而是直接执行所有指令。
若当前需要的页没在内存里,就寻找最近最少使用的页,也就是ltu[]最小的页,即最近一次使用时间离现在最久的页,然后替换掉它。
或者在内存还未满时,直接写入,这个我以初始化内存里所有页为-1来实现。
若已经在内存里了,则只遍历内存内的页,把当前页的最近使用时间改一下即可。
3)OPT算法定义数组ntu[], 即next_time_use来记录下一次被使用的时间,即将来最快使用时间。
初始化为-1.开始时预调页填满内存里的页。
同样利用变量ptr来表示下一个要存放的位置从而控制预调页的过程。
接着初始化ntu数组为-1。
然后求出每一页下一次被使用的指令号,以此代替使用时间。
如果所有剩下的序列都没有用该页时,则还是-1.这种值为-1的页显然是最佳替换对象。
然后执行所有剩下的指令。
当该页不在内存里时,遍历ntu数组,遇到-1的直接使用该页,没有则用ntu[]值最大的,也就是最晚使用的。
无论该页在不在内存里,因为这一次已经被使用了,所以都应该更新这个页的ntu[],只需往前看要执行的页流,记录下第一个遇到的该页即可。
任务四、请求分页存储管理(虚拟存储)一、实验目的通过请求分页存储管理的设计,让学生了解虚拟存储器的概念和实现方法。
进行运行时不需要将所有的页面都调入内存,只需将部分调入内存,即可运行,在运行的过程中若要访问的页面不在内存时,则需求有请求调入的功能将其调入。
假如此时若内存没有空白物理块,则通过页面置换的功能将一个老的不用的页面淘汰出来,其中淘汰的算法有多种。
二、实验内容模拟仿真请求分页调度算法,其中淘汰的算法可选下列其一1、先进先出算法2、最近最久算法3、CLOCK算法三、实验代码#include<iostream>#include<vector>using namespace std;int n;typedef struct Queue{int time;int data;struct Queue *next;}Queue,*QueuePtr;typedef struct {QueuePtr front;QueuePtr rear;}LinkQueue;//fifo=======================================void InitQueue(LinkQueue &Q);void FiFoEnQueueRear(LinkQueue &Q,int e,vector<int> &v);void FiFoDeQueueFront(LinkQueue &Q);inline void PrintQueue(LinkQueue &Q);void FiFoFiFoDoQueueEarly(LinkQueue &Q,int a,vector<int> &v);void FiFoDoQueue(LinkQueue &Q,int a,vector<int> &v);inline int PanDuan(LinkQueue &Q,int a);inline int YeMianCount(LinkQueue &Q);void fifo();//lru=============================================void InitQueue(LinkQueue &Q);void EnQueueMid(LinkQueue &Q,int e,QueuePtr p,vector<int> &v);void EnQueueTheFist(LinkQueue &Q,int e);void PrintQueue(LinkQueue &Q);//void ZhiZhenInit(int n);void DoQueueEarly(LinkQueue &Q,int e,vector<int> &v);void EnQueueRear(LinkQueue &Q,int e,QueuePtr p,vector<int> &v);//void DeQueueFront(LinkQueue &Q);QueuePtr ZhiZhen(LinkQueue &Q,int e);void EnQueue(LinkQueue &Q,int e,vector<int> &v);//void DeQueue(LinkQueue &Q,QueuePtr p);int PanDuan(LinkQueue &Q,int a);int YeMianCount(LinkQueue &Q);void lru();QueuePtr OptimalZhiZhen(LinkQueue &Q,int e);//求出需要置换的页面的上一个页面的位置void EnQueue(LinkQueue &Q,int e,vector<int> &v,int i,vector<int> &vc);inline int YeMianCount(LinkQueue &Q);//使用内敛函数,提高性能inline int Destance(vector<int> &v,int i);inline void SubbDestance(LinkQueue &Q);//=================================================int main(){int k;for(;;){cout<<"请选择!"<<endl;cout<<"1——FiFo算法"<<endl;cout<<"2——LRU算法"<<endl;cout<<"0——退出"<<endl;cin>>k;if(k==0)break;else{switch(k){case 1:fifo();break;case 2:lru();break;default:cout<<" 请从以上的选择中选择一个选项!!"<<endl;}}}}//fifo========================================void InitQueue(LinkQueue &Q){Q.front=Q.rear=(QueuePtr)malloc(sizeof(Queue));if(!Q.front)cout<<"initqueue worng!"<<endl;Q.front->next=NULL;//return OK;}void FiFoEnQueueRear(LinkQueue &Q,int e,vector<int> &v){ QueuePtr p;p=(QueuePtr)malloc(sizeof(Queue));if(!p)cout<<"cannot malloc EnQueue of the p"<<endl;p->data=e;p->next=NULL;Q.rear->next=p;Q.rear=p;v.push_back(e);//cout<<p->data;//return OK;}void FiFoDeQueueFront(LinkQueue &Q){QueuePtr p;if(Q.front==Q.rear)cout<<"the Queue is empty,cannot delete !!"<<endl;p=Q.front->next;Q.front->next=p->next;free(p);if(Q.rear==p)Q.rear=Q.front;//return OK}void PrintQueue(LinkQueue &Q){QueuePtr p;if(Q.front==Q.rear)cout<<"the Queue is empty,cannot print!"<<endl;p=Q.front;for(p=Q.front;p->next!=NULL;p=p->next){cout<<p->next->data<<" ";}cout<<endl;//retrun OK;}void FiFoFiFoDoQueueEarly(LinkQueue &Q,int a,vector<int> &v){ QueuePtr p;int count=0;//设置标志位,记录重复的个数。
简述请求分页存储管理方式请求分页存储管理方式是一种非常实用的存储管理方式,它可以将大量数据分成多页存储,从而增加系统的可扩展性和可维护性。
本文将分步骤阐述请求分页存储管理方式的实现过程。
1. 设计数据库表结构首先,我们需要设计出适合分页存储的数据库表结构。
通常,我们需要将数据表按照某种规则分成多个页面,每个页面中包含相同数量的数据。
例如,如果需要将1000条数据分成10页,那么每个页面应该包含100条数据。
2. 编写查询语句在设计好数据库结构之后,我们需要编写查询语句来查询数据并将其分页。
我们可以使用LIMIT关键字来限制查询结果的数量,并使用OFFSET关键字来指定从哪个位置开始查询。
例如,如果需要查询第2页的数据,那么我们可以使用以下SQL语句:SELECT * FROM table_name LIMIT 100 OFFSET 100;这将返回第101到第200条数据。
3. 编写分页控件分页控件是实现分页存储的重要组成部分。
它通常包含一个页面选择器和一个数据显示区域。
我们可以使用JavaScript和CSS来创建翻页效果和样式。
例如,我们可以使用以下代码创建一个简单的页面选择器:```<div class="pagination"><a href="#">1</a><a href="#">2</a><a href="#">3</a><a href="#">4</a><a href="#">5</a></div>```4. 实现异步加载异步加载是将页面动态加载到用户界面中的一种技术。
它可以大大提高页面加载速度和用户体验。
我们可以使用AJAX等技术来实现异步加载。
操作系统-请求页式存储管理实验报告分析解析实验背景在计算机系统中,内存是一项很重要的资源。
其中,操作系统需要管理内存,以便为用户进程和内核提供适当的内存空间。
页式内存管理是操作系统能够管理和维护内存的一种方式。
在页式内存管理中,主存分为固定大小的框架,称为页框,而进程的地址空间被分割为固定大小的页。
页式内存管理系统采用了一种称为“请求页式存储”的技术,允许进程只存取正在使用的那些页面。
这样可以节省空间,并且提高了处理器访问内存的速度。
实验环境本次实验使用的操作系统是 Ubuntu 20.04 LTS 操作系统。
实验目标本次实验的主要目标是通过模拟请求页式内存管理系统,来了解和深入理解页式内存管理技术。
本次实验需要完成以下任务:1.编写一个简单的请求页式存储模拟器;2.使用该模拟器对作业和内存进行模拟;3.分析模拟结果并撰写实验报告。
实验过程阅读并理解作业说明在开始实验之前,我们首先需要阅读和了解具体的作业说明。
在本次实验中,我们需要完成一个请求页式存储模拟器,以及使用该模拟器对作业与内存进行模拟。
编写模拟器在了解了作业说明后,我们开始按照作业的要求,编写请求页式内存管理模拟器。
在这里,我们需要使用到Python 编程语言。
实际上,我们在编写该模拟器时,主要分为以下几步:1.文件操作:首先,我们需要通过读取文件中的数据来模拟进程对内存的请求。
在输入文件中,每一行表示一个请求,包含了进程 ID、请求的地址和访问类型。
2.内存分配:接着,我们需要模拟请求页式内存管理系统中对于内存分配的操作,即在访问时,将需要的页加载到内存中,如果内存已满,则需要选择一个页面将其从内存中移除,为新的页面腾出空间。
3.页面置换:如果进行页面置换,则需要选出最久未访问的页面并移出内存,空出空间用于新的页面,这就是所谓的“最久未使用”(LRU)策略。
进行模拟有了模拟器之后,我们就可以针对不同的作业和内存大小进行实验。
在实验的过程中,我们可以观察不同大小的内存和不同的作业怎样影响模拟的结果。
《网络操作系统》课程设计报告书题目:请求调页存储管理方式的模拟学号:学生姓名:指导教师:年月日目录一. 实验内容................................................... 错误!未定义书签。
二. 实验目的................................................... 错误!未定义书签。
三. 设计思想................................................... 错误!未定义书签。
四. 程序流程图................................................. 错误!未定义书签。
五. 程序清单................................................... 错误!未定义书签。
六. 运行结果及分析............................................. 错误!未定义书签。
七. 总结....................................................... 错误!未定义书签。
一、实验内容1.假设每个页面中可存放10条指令,分配给作业的内存块数为4。
2.用C语言或C++语言模拟一个作业的执行过程,该作业共有320条指令,即它的地址空间为32页,目前它的所有页都还未调入内存。
在模拟过程中,如果所访问的指令已在内存,则显示其物理地址,并转下一条指令。
如果所访问的指令还未装入内存,则发生缺页,此时需记录缺页的次数,并将相应页调入内存。
如果4个内存块均已装入该作业,则需进行页面置换,最后显示其物理地址,并转下一条指令。
在所有320指令执行完毕后,请计算并显示作业运行过程中发生的缺页率。
3.置换算法:请分别考虑最佳置换算法(OPT)、先进先出(FIFO)算法和最近最久未使用(LRU)算法。
请求分页式存储管理一、问题描述设计一个请求页式存储管理方案,为简单起见。
页面淘汰算法采用 FIFO 页面淘汰算法,并且在淘汰一页时,只将该页在页表中修改状态位。
而不再判断它是否被改写过,也不将它写回到辅存。
二、基本要求页面尺寸 1K ,输入进程大小(例如 5300bytes),对页表进行初始化页表结构如下:页号物理块号状态位0 2 True (在主存 )1 12 False (在辅存 )3 04 False (在辅存 )5 False (在辅存 )系统为进程分配 3 个物理块(页框),块号分别为 0、1、 2,页框管理表(空闲块表):物理块号是否空闲0 true1 true2 true任意输入一个需要访问的指令地址流(例如:3635、 3642、 1140、 0087、 1700、 5200、4355,输入负数结束),打印页表情况。
每访问一个地址时,首先要计算该地址所在的页的页号,然后查页表,判断该页是否在主存——如果该页已在主存,则打印页表情况;如果该页不在主存且页框未满(查空闲块表,找到空闲块),则调入该页并修改页表,打印页表情况;如果该页不在主存且页框已满,则按 FIFO 页面淘汰算法淘汰一页后调入所需的页,修改页表,打印页表情况。
存储管理算法的流程图见下页。
三、实验要求完成实验内容并写出实验报告,报告应具有以下内容:1、实验目的。
2、实验内容。
3、程序及运行情况。
4、实验过程中出现的问题及解决方法。
#include<stdio.h>#include<stdlib.h>int PUB[20][3];int ABC[3][2]={{0,1},{1,1},{2,1}};//物理块int key=0;void output(int size){//打印int i,j;printf(" 页号 \t\t 物理块号 \t\t 状态位 \n\n");for(i=0;i<size;i++){printf(" %d\t\t%d\t\t\t%d\n\n",PUB[i][0],PUB[i][1],PUB[i][2]);}printf(" 物理块号 \t\t 是否空闲 \n\n");for(i=0;i<3;i++){printf(" %d\t\t\t%d\n\n",ABC[i][0],ABC[i][1]);}}void main(){int size;int i,j;int address=0;int select=0;printf(" 请输入进程大小\n");scanf("%d",&size);if(size<=0 || size>20000){printf(" 进程大小超出范围\n");exit(0);}size%1000==0 ? size=size/1000 : size=size/1000+1;for(i=0;i<size;i++){PUB[i][0]=i;//页号PUB[i][1]=0; //物理块号PUB[i][2]=0; //状态位}output(size);while(1){printf(" 输入指令地址\n");scanf("%d",&address);if(address<0 || address>20000){printf(" 地址超出范围 \n");exit(0);}address%1000==0 ? address=address/1000 : address=address/1000;if(PUB[address][2]==0) //不在主存{if(ABC[2][1]==0)//满了{printf(" 满了 \n");key++;if(select!=address)for(i=0;i<size;i++){if(PUB[i][1]==key){PUB[i][1]=0;PUB[i][2]=0;}}PUB[address][1]=key;PUB[address][2]=1;key++;if(key>3) key=1;}if(ABC[2][1]==1)//没满{printf(" 没满 \n");for(i=0;i<3;i++){if(ABC[i][1]==1){ABC[i][1]=0;PUB[address][1]=i+1;PUB[address][2]=1;break;}}}output(size);}else{printf(" 该页已在内存 \n");output(size);}select=address;}}开始输入进程大小,对页表进行初始化输入要访问的地址0<= 地址 <=进程大小结束是计算页号 , 查页表是该页已是否在主存页框未满是调入该页并修改页表淘汰一页后调入所需的页,修改页表打印页表。
操作系统实验三报告一.实验名称:分页存储管理二.实验目的:了解分页存储管理在内存空间分配的作用三.实验内容:分页存储管理是将一个进程的逻辑地址空间分成若干个大小相等的片,称为页面或页,并为各页加以编号,相应的,也把内存空间分成与页面相同大小的若干个存储块,称为物理块或页框,同样加以编号,在为进程分配内存时,以块为单位将进程的若干个也分别装入到多个可以不相邻的物理块中。
系统为每个进程建立了一张页面映像表,简称页表。
位示图是利用二进制的一位来表示磁盘中的一个盘块的使用情况,这里用位示图来表示内存分配情况。
四.实验代码#include <stdafx.h>#include <stdlib.h>#include <stdio.h>typedef int datatype;typedef struct node{datatype pageNum,blockNum;struct node *next;}linknode;typedef linknode *linklist;linklist creatlinklist(int n){linklist head,r,s;int x,y,i=0;head=r=(linklist)malloc(sizeof(linknode));printf("开始创建页表\n");printf("请分别输入页表的页号及块号(-1表示空):\n");printf("\n页号块号\n");while (i<n){scanf("%d %d",&x,&y);s=(linklist)malloc(sizeof(linknode));s->pageNum=x;s->blockNum=y;r->next=s;r=s;i++;}r->next=NULL;return head;}void print(linklist head){linklist p;p=head->next;printf("\n该页表为:");printf("\n页号块号\n");while(p){printf("%d%7d\n",p->pageNum,p->blockNum );p=p->next;}printf("\n");}/*初始化位示图,将值全置为零,0表示空闲状态*/void init(int g[100][100],int N){int i,j;for(i=0;i<100;i++){for(j=0;j<100;j++){g[i][j]=0;}}g[N+1][0]=N*N;}/*对作业的每一个页进行分配对应位示图里的块*/linklist Dis(linklist head,int g[100][100],int n,int N){linklist p;int i,j;p=head->next;if(n<=g[N+1][0]){while(p){for(i=0;i<N;i++){for(j=0;j<N;j++){if(g[i][j]==0){p->blockNum=N*i+j;g[i][j]=1;g[N+1][0]--;break;}}break;}p=p->next;}return head;}}/*回收已经完成的页*/linklist Recy(linklist head,int g[100][100],int n,int N){int i,j;linklist p;p=head->next;while(p&&p->pageNum!=n){p=p->next;}if(p){i=p->blockNum/N;j=p->blockNum%N;g[i][j]=0;g[N+1][0]++;p->blockNum=-1;}return head;}/*打印位示图*/void printStr(int g[100][100],int N) {int i,j;printf("此时位示图为:\n ");for(i=0;i<N;i++){printf(" ");printf("%d",i);}printf("\n");for(i=0;i<N;i++){printf("%d",i);for(j=0;j<N;j++){printf(" ");printf("%d",g[i][j]);}printf("\n");}}void main(){int n,N,x,y;int graph[100][100];linklist head;printf("输入位示图的字长:");scanf("%d",&N);printf("输入作业的页数:");scanf("%d",&n);head=creatlinklist(n);print(head);init(graph,N);printStr(graph,N);printf("\n现在进行作业分配:");head=Dis(head,graph,n,N);print(head);printStr(graph,N);printf("是否回收已完成的页,“是”1,“否”0:");scanf("%d",&x);if(x) //判断是否要回收{printf("\n请输入您要回收的页号:");scanf("%d",&y);head=Recy(head,graph,y,N);print(head);printStr(graph,N);}}五.实验截图:六.实验心得:通过这次实验,了解到分页存储管理是将一个进程的逻辑地址空间分成若干个大小相等的片,称为页面或页,并为各页加以编号,相应的,也把内存空间分成与页面相同大小的若干个存储块,称为物理块或页框,同样加以编号,在为进程分配内存时,以块为单位将进程的若干个也分别装入到多个可以不相邻的物理块中。
操作系统实验报告三存储器管理实验操作系统实验报告三:存储器管理实验一、实验目的本次存储器管理实验的主要目的是深入理解操作系统中存储器管理的基本原理和方法,通过实际操作和观察,掌握内存分配与回收的算法,以及页面置换算法的工作过程和性能特点,从而提高对操作系统资源管理的认识和实践能力。
二、实验环境本次实验使用的操作系统为 Windows 10,编程语言为 C++,开发工具为 Visual Studio 2019。
三、实验内容1、内存分配与回收算法实现首次适应算法(First Fit)最佳适应算法(Best Fit)最坏适应算法(Worst Fit)2、页面置换算法模拟先进先出页面置换算法(FIFO)最近最久未使用页面置换算法(LRU)时钟页面置换算法(Clock)四、实验原理1、内存分配与回收算法首次适应算法:从内存的起始位置开始,依次查找空闲分区,将第一个能够满足需求的空闲分区分配给进程。
最佳适应算法:在所有空闲分区中,选择能够满足需求且大小最小的空闲分区进行分配。
最坏适应算法:选择空闲分区中最大的分区进行分配。
2、页面置换算法先进先出页面置换算法:选择最早进入内存的页面进行置换。
最近最久未使用页面置换算法:选择最近最长时间未被访问的页面进行置换。
时钟页面置换算法:给每个页面设置一个访问位,在页面置换时,从指针指向的页面开始扫描,选择第一个访问位为0 的页面进行置换。
五、实验步骤1、内存分配与回收算法实现定义内存分区结构体,包括分区起始地址、大小、是否已分配等信息。
实现首次适应算法、最佳适应算法和最坏适应算法的函数。
编写测试程序,创建多个进程,并使用不同的算法为其分配内存,观察内存分配情况和空闲分区的变化。
2、页面置换算法模拟定义页面结构体,包括页面号、访问位等信息。
实现先进先出页面置换算法、最近最久未使用页面置换算法和时钟页面置换算法的函数。
编写测试程序,模拟页面的调入和调出过程,计算不同算法下的缺页率,比较算法的性能。
【操作系统】请求分页储存管理⽅式常规存储器管理⽅式(基本分页、基本分段)的特征(1) ⼀次性。
都要求将作业所有装⼊内存后⽅能执⾏。
很多作业在每次执⾏时,并不是其所有程序和数据都要⽤到。
假设⼀次性地装⼊其所有程序,造成内存空间的浪费。
(2) 驻留性。
作业装⼊内存后,便⼀直驻留在内存中,直⾄作业执⾏结束。
虽然执⾏中的进程会因I/O⽽长期等待,或有的程序模块在执⾏过⼀次后就不再须要(执⾏)了,但它们都仍将继续占⽤宝贵的内存资源。
虚拟存储器的定义应⽤程序在执⾏之前,没有必要所有装⼊内存,仅须将那些当前要执⾏的少数页⾯或段先装⼊内存便可执⾏,其余部分暂留在盘上。
程序在执⾏时,假设它所要訪问的页(段)已调⼊内存,便可继续执⾏下去;但假设程序所要訪问的页(段)尚未调⼊内存(称为缺页或缺段),此时程序应利⽤OS所提供的请求调页(段)功能,将它们调⼊内存,以使进程能继续执⾏下去。
假设此时内存已满,⽆法再装⼊新的页(段),则还须再利⽤页(段)的置换功能,将内存中临时不⽤的页(段)调⾄盘上,腾出⾜够的内存空间后,再将要訪问的页(段)调⼊内存,使程序继续执⾏下去。
虚拟存储器是指具有请求调⼊功能和置换功能,能从逻辑上对内存容量加以扩充的⼀种存储器系统。
其逻辑容量由内存容量和外存容量之和所决定,其执⾏速度接近于内存速度,⽽每位的成本却⼜接近虚拟存储器于外存。
可见,虚拟存储技术是⼀种性能很优越的存储器管理技术,故被⼴泛地应⽤于⼤、中、⼩型机器和微型机中。
请求分页存储管理⽅式1、定义:请求分页系统是建⽴在基本分页系统的基础上,为了能⽀持虚拟存储器功能⽽添加了请求调页功能和页⾯置换功能。
2、页表机制在请求分页系统中所须要的主要数据结构是页表。
其基本作⽤仍然是将⽤户地址空间中的逻辑地址变换为内存空间中的物理地址。
因为仅仅将应⽤程序的⼀部分调⼊内存,另⼀部分仍在盘上,故须在页表中再添加若⼲项,供程序(数现对当中各字段说明例如以下:(1) 状态位P:⽤于指⽰该页是否已调⼊内存,供程序訪问时參考。
一、实验目的1. 理解分页存储管理的基本原理和方法;2. 掌握分页存储管理中的页面置换算法;3. 熟悉分页存储管理的实现过程;4. 培养动手实践能力,提高对操作系统内存管理的认识。
二、实验环境1. 操作系统:Windows 102. 编程语言:C++3. 开发环境:Visual Studio 2019三、实验原理分页存储管理是一种将内存划分为固定大小的页面,并将进程的地址空间划分为同样大小的逻辑页的内存管理方式。
分页存储管理的主要优点是消除了外部碎片,提高了内存的利用率。
以下是分页存储管理的关键概念:1. 页面:内存划分为固定大小的块,称为页面。
页面大小通常为4KB或8KB。
2. 逻辑页:进程的地址空间划分为同样大小的块,称为逻辑页。
3. 页表:用于记录逻辑页与物理页的映射关系。
四、实验内容1. 初始化内存:创建一个模拟的内存空间,用数组表示。
初始化时,内存中的一部分页面被占用,其他页面为空闲状态。
2. 进程调度:模拟进程的调度过程,包括进程的创建、销毁和页面请求。
3. 页面置换算法:实现不同的页面置换算法,如先进先出(FIFO)、最近最少使用(LRU)等。
4. 页面映射:根据进程的页面请求,查找页表,将逻辑页映射到物理页。
5. 页面回收:当进程销毁或页面不再需要时,回收对应的物理页。
五、实验步骤1. 初始化内存:创建一个大小为1024的数组,模拟内存空间。
其中,前256个元素表示被占用的页面,其余元素表示空闲页面。
2. 创建进程:模拟进程的创建过程,包括进程的编号、所需页面数和页面请求序列。
3. 页面置换算法:实现FIFO和LRU两种页面置换算法。
FIFO算法按照进程创建的顺序进行页面置换;LRU算法根据页面在内存中驻留时间的长短进行页面置换。
4. 页面映射:根据进程的页面请求,查找页表,将逻辑页映射到物理页。
如果请求的页面已在内存中,则直接返回物理页号;如果请求的页面不在内存中,则根据页面置换算法替换一个页面,并将请求的页面加载到内存中。
操作系统模拟实验实验名称:请求分页存储管理模拟实验实验目的:通过实验了解windows系统中的线程同步如何使用,进一步了解操作系统的同步机制。
实验内容:调用Windows API,模拟解决生产者-消费者问题;思考在两个线程函数中哪些是临界资源?哪些代码是临界区?哪些代码是进入临界区?哪些代码是退出临界区?进入临界区和退出临界区的代码是否成对出现?学习Windows API中的如何创建线程,互斥,临界区等。
程序运行结果:源程序:#include "stdAfx.h"//包含头文件以支持多线程#include "windows.h"#include "stdio.h"//用于标志所有的子线程是否结束//每次子线程结束后,此值便加1。
static long ThreadCompleted = 0;//互斥量HANDLE mutex;//信号量,用于生产者通知消费者HANDLE full;//信号量,用于消费者通知生产者HANDLE empty;//信号量,当所有的子线程结束后,通知主线程,可以结束。
HANDLE evtTerminate;//生产标志#define p_item 1//消费标志#define c_item 0//哨兵#define END 10//缓冲区最大长度const int max_buf_size=11;const int cur_size=10;//缓冲区定义int BUFFER[max_buf_size];//放消息指针int in=0;//取消息指针int out=0;int front=0;int tail=0;int sleep_time=1000;bool flag=true;//线程函数的标准格式unsigned long __stdcall p_Thread(void *theBuf);unsigned long __stdcall c_Thread(void *theBuf);//打印缓冲区内容void PrintBuf(int buf[],int buf_size);int main(int argc, char* argv[]){//初始化缓冲区unsigned long TID1, TID2;for(int i=0;i<cur_size;i++)BUFFER[i]=0;//互斥量和信号量的创建,函数用法可查看MSDNmutex=CreateMutex(NULL,false,"mutex");full=CreateSemaphore(NULL,0,1,"full");empty=CreateSemaphore(NULL,max_buf_size,max_buf_size,"empty");evtTerminate = CreateEvent(NULL, FALSE, FALSE, "Terminate");//创建一个生产者线程和消费者线程。
分页存储管理实验报告分页存储管理实验报告篇一:分页存储管理的模拟实验上机报告分页存储管理的模拟实验上机报告页面管理的基本原理及方法:各进程的虚拟空间被划分成若干个长度相等的页(page)。
页长的划分和内存外存之间的数据传输速度以及内存大小等有关。
页式管理还把内存空间也按也的大小划分为页面(page frame)。
然后把页式虚拟地址与内存页面物理地址建立一一对应页表,并用相应的硬件地址变换机构,来解决离散地址变换问题。
在作业或进程开始执行之前,把该作业或进程的程序段和数据全部装入内存的各个页面中,并通过页表(page mapping table)和硬件地址变换机构实现虚拟地址到内存物理地址的地址映射。
1. 内存页面分配静态页面管理的第一步是为要求内存的作业或进程分配足够的页面。
系统依靠存储页面表,请求表及页表来完成内存的分配工作。
a. 页表页表由页号与页面号组成。
如右图所示页表的大小由进程或作业的长度决定。
例如,对于一个每页长1k,大小为20k的进程来说,如果一个内存单元存放一个页表项,则只要分配给该页表20个存储单元即可。
页式管理是每个进程至少拥有一个页表。
实验中对页表的定义如下(采用数组形式,数组下标表示页号,数组单元存放与数组下标(页号)相应的页面号):int pagetable[100] b.请求表(作业申请表)请求表用来确定作业或进程的虚拟空间的各页在内存中的对应位置。
为了完成这个认为,系统必须知道每个作业或进程的页表起始地址(本实验中假定为0)和长度,以进行内存分配和地址变换。
另外请求表中还包括每个作业或进程所要求的页面数。
请求表整个系统一张,实验中对请求表的定义如下(采用结构体数组形式,并将页表也作为其中一个成员(即域)):#define u 5 struct application_table{char name[8];/*作业名*/int size;/*作业大小――即将上表中的请求页面数改用字节表示*/int paddress; /*页表起始地址*/ int length;/*页表长度――以页面数表示*/int state; /*内存的分配状态,以分配的用1表示,未分配的用0表示*/int pagetable[100];/*页表,放在这里是为了方便虚地址转换及作业撤销的操作*/ }application[u];c.存储页面表(本实验中采用位示图法)位示图也是整个系统一张,它指出内存各页面是否已被分配出去,以及未分配页面的总数。
实验四请求分页存储管理模拟实验一:实验目的通过对页面、页表、地址转换和页面置换过程的模拟,加深对请求分页存储管理系统的原理和实现技术的理解;二:实验内容假设每个页面可以存放10条指令,分配给进程的存储块数为4;用C语言或Pascal语言模拟一进程的执行过程;设该进程共有320条指令,地址空间为32个页面,运行前所有页面均没有调入内存;模拟运行时,如果所访问的指令已经在内存,则显示其物理地址,并转下一条指令;如果所访问的指令还未装入内存,则发生缺页,此时需要记录缺页产生次数,并将相应页面调入内存,如果4个内存块已满,则需要进行页面置换;最后显示其物理地址,并转下一条指令;在所有指令执行完毕后,显示进程运行过程中的缺页次数和缺页率;页面置换算法:分别采用OPT、FIFO、LRU三种算法;进程中的指令访问次序按如下原则生成:50%的指令是顺序执行的;25%的指令是均匀分布在低地址部分;25%的指令是均匀分布在高地址部分;三:实验类别分页存储管理四:实验类型模拟实验五:主要仪器计算机六:结果OPT:LRU: FIFO:七:程序include<>include<>include<>define blocknum 4agenum=-1;blocki.accessed=0;m=0;}}int pageExistint curpageagenum == curpagereturn i; agenum==-1return i; ccessed > blockpos.accessedpos = i; agenum = -1{printf" %02d ",blocki.pagenum;printf"%p |",&blocki.pagenum;}}printf"\n";}void randamagenum = curpage; agenum= numj/10{blockk.accessed = 1000;} ccessed = j;break;}}}position = findReplace;agenum = curpage;agenum = curpage; agenum = curpage;display;n++; ccessed = -1;ccessed++;}}printf"缺页次数:%d\n",n;printf"缺页率:%f%%\n",n/100;}void FIFO{int n=0;agenum=curpage; agenum = curpage; //将此页面调入内存n++;display;}}}printf"缺页次数:%d\n",n;printf"缺页率:%f%%\n",n/100;}void main{int choice;printf"请求分页存储管理模拟系统\n";randam;printf"此进程的页面调用序列如下\n";pagestring;whilechoice = 4{printf"1:OPT 2:LRU 3:FIFO 4:退出\n";printf"请选择一种页面置换算法:";scanf"%d",&choice;init;switchchoice{case 1:printf"最佳置换算法OPT:\n";printf"页面号物理地址页面号物理地址页面号物理地址页面号物理地址\n";OPT;break;case 2:printf"最近最久未使用置换算法LRU:\n";printf"页面号物理地址页面号物理地址页面号物理地址页面号物理地址\n";LRU;break;case 3:printf"先进先出置换算法FIFO:\n";printf"页面号物理地址页面号物理地址页面号物理地址页面号物理地址\n";FIFO;break;}}}。
实验3请求调页存储管理方式的模拟1实验目的通过对页面、页表、地址转换和页面置换过程的模拟,加深对请求调页系统的原理和实现过程的理解。
2实验内容(1)假设每个页面中可存放10条指令,分配给一作业的内存块数为4。
(2)模拟一作业的执行过程。
该作业共有320条指令,即它的地址空间为32页,目前它的所有页都还未调入内存。
在模拟过程中,如果所访问的指令已经在内存中,则显示其物理地址,并转下一条指令。
如果所访问的指令还未装入内存,则发生缺页,此时需记录缺页的次数,并将相应页调入内存。
如果4个内存块中均已装入该作业,则需进行页面置换。
最后显示其物理地址,并转下一条指令。
在所有320条指令执行完毕后,请计算并显示作业运行过程中发生的缺页率。
(3)置换算法:请分别考虑OPT、FIFO和LRU算法。
(4)作业中指令的访问次序按下述原则生成:•50%的指令是顺序执行的。
•25%的指令是均匀分布在前地址部分。
•25%的指令时均匀分布在后地址部分。
代码:package mainDart;import java.util.ArrayList;import java.util.List;import java.util.Random;public class FIFO {private static int times=0;//记录置换内存页面的次数/*** 随机产生0~319之间的数* 产生320条指令** @return 包含320条指令的数组*/public static int[] productNumber(){int order[] = new int[320];//数组存储的数字表示指令Random rand = new Random();for(int i=0;i<320;i++){if(i%4==0){order[i]=rand.nextInt(319); //0<=order<319}else if(i%4==1){order[i]=order[i-1]+1;//1<=order<320}else if(i%4==2){order[i]= rand.nextInt(order[i-1]);}else if(i%4==3){order[i]=order[i-1]+rand.nextInt(320-order[i-1]);}}return order;}/*** 打印链表* @param list*/public static void printList(List<Integer> list){for(int temt:list){System.out.print(temt+"\t");}System.out.println();}/*** 先进先出算法* 总是淘汰最先进入内存的页面* 在实现的时候,记录上一次所替换的页面在内存的下标,则本次要替换的位置就是上次下标+1的位置,并且下标是0~3循环的* @param memoryNum* @param page*/public static void FIFOChangePage(List<Integer> memoryNum,int page){int index = FIFOChangePage(memoryNum,page,++times);memoryNum.remove(index);memoryNum.add(index, page);}/*** 返回本次替换的页面在内存中的位置* @param memoryNum* @param page* @param times记录替换页面的次数,第一次替换的是内存第0个单元* @return*/public static int FIFOChangePage(List<Integer> memoryNum,int page,int times) {if(times==1){return 0;}int index = (FIFOChangePage(memoryNum,page,times-1)+1)%4;return index;}public static void main(String[] args) {int[] order = productNumber();System.out.println("320条随机指令数:");for(int i =0;i<order.length;i++){System.out.print(order[i]+"\t");if((i+1)%10==0){System.out.println();}}List<Integer> memoryNum= new ArrayList<Integer>(4);//内存块存储的页面int count=0;//记录缺页次数for(int i=0;i<320;i++){int page = order[i]/10;if(memoryNum.contains(page)) //若该指令所在页面已经在内存,输出该页面所在内存块的号{}else//没在内存,发生缺页,需要判断内存块是否存满,{if(memoryNum.size()<4) //内存没满,直接将所需页面调入内存{memoryNum.add(page);}else//内存存满,需要调用页面置换算法,进行页面置换{FIFOChangePage(memoryNum,page);//先进先出算法}count++;//记录缺页次数}printList(memoryNum);//打印内存所调入页面的情况}System.out.println("缺页率:"+(double)count/320);}}package mainDart;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Random;public class LRU {/*** 随机产生0~319之间的数* 产生320条指令** @return 包含320条指令的数组*/public static int[] productNumber(){int order[] = new int[320];//数组存储的数字表示指令Random rand = new Random();for(int i=0;i<320;i++){if(i%4==0){order[i]=rand.nextInt(319); //0<=order<319}else if(i%4==1){order[i]=order[i-1]+1;//1<=order<320}else if(i%4==2){order[i]= rand.nextInt(order[i-1]);}else if(i%4==3){order[i]=order[i-1]+rand.nextInt(320-order[i-1]);}}return order;}/*** 打印链表* @param list*/public static void printList(List<Integer> list){for(int temt:list){System.out.print(temt+"\t");}System.out.println();}/*** 最近最久未使用算法* @param order*/public static void LRUChangePage(int [] order){List<Integer> memoryNum = new ArrayList<Integer>(4);//内存块int[] timeFlag =new int[]{-1,-1,-1,-1}; //用来记录内存当中各单元未被访问的时间值int count=0;//记录缺页次数for(int i=0;i<320;i++){int page = order[i]/10;if(memoryNum.contains(page)) //若该指令所在页面已经在内存{int index = memoryNum.indexOf(page);timeFlag[index]=0;//将时间变为0 }else//没在内存,发生缺页,需要判断内存块是否存满,{if(memoryNum.size()<4) //内存没满,直接将所需页面调入内存{//将没有命中的所有页面的时间加一for(int in=0;in<4;in++){if(timeFlag[in]!=-1){timeFlag[in]+=1;}}//将page加入内存并将时间置为0memoryNum.add(page);timeFlag[memoryNum.indexOf(page)]=0;}else//内存存满,需要调用页面置换算法,进行页面置换{int maxIn=-1;//记录拥有最大时间值的标记的下标int maxT=-1;//记录最大的时间值for(int in=0;in<4;in++)//找出内存中时间值最大的进行替换{if(timeFlag[in]>maxT){maxT=timeFlag[in];maxIn=in;}}memoryNum.remove(maxIn);memoryNum.add(maxIn,page);timeFlag[maxIn]=0;//将没有命中的所有页面的时间加一for(int in=0;in<4;in++){if(in!=maxIn){timeFlag[in]+=1;}}}count++;//记录缺页次数}printList(memoryNum);//打印内存所调入页面的情况}System.out.println("缺页率:"+(double)count/320);}public static void main(String[] args) {int[] order = productNumber();System.out.println("320条随机指令数:");for(int i =0;i<order.length;i++){System.out.print(order[i]+"\t");if((i+1)%10==0){System.out.println();}}LRUChangePage(order);}}package mainDart;import java.util.ArrayList;import java.util.List;import java.util.Random;public class Optimal {/*** 随机产生0~319之间的数* 产生320条指令** @return 包含320条指令的数组*/public static int[] productNumber(){int order[] = new int[320];//数组存储的数字表示指令Random rand = new Random();for(int i=0;i<320;i++){if(i%4==0){order[i]=rand.nextInt(319); //0<=order<319}else if(i%4==1){order[i]=order[i-1]+1;//1<=order<320}else if(i%4==2){order[i]= rand.nextInt(order[i-1]);}else if(i%4==3){order[i]=order[i-1]+rand.nextInt(320-order[i-1]);}}return order;}/**** @param order320条指令数组* @return 返回一个链表,依次保存着320条指令每条指令所在的页面*/public static List<Integer> pageSeq(int[] order){List<Integer> pageSeq = new ArrayList<Integer>();for(int temp:order){pageSeq.add(temp/10);}return pageSeq;}/*** 打印链表* @param list*/public static void printList(List<Integer> list){for(int temt:list){System.out.print(temt+"\t");}System.out.println();}/*** 最佳置换算法* 根据当前已经在内存中的页面在之后被需要的先后进行置换** @param pageSeq 整个320条指令,从头到尾所需要的页面* @param memoryNum 已满的内存空间* @param page等待被调入内存的页面*/public static void OptimalChangePage(List<Integer> pageSeq,int start,List<Integer> memoryNum,int page){int maxSeq=-1,index=0;for(int pageNum:memoryNum) //遍历内存{for(int i=start;i<pageSeq.size();i++){if(pageNum==pageSeq.get(i)){if(i>maxSeq){maxSeq=i;}break;}}}if(maxSeq>-1)//maxSeq==-1说明内存当中的四个页面在将来都不会再被使用,这时默认将内存块中的第一个页面置换出{index = memoryNum.indexOf(pageSeq.get(maxSeq));//记录将要被置换的那个页面所在内存位置}memoryNum.remove(index);//将内存中将来最久被使用的页面删除memoryNum.add(index, page);//将需要调入的页面加入内存}public static void main(String[] args) {int[] order = productNumber();System.out.println("320条随机指令数:");for(int i =0;i<order.length;i++){System.out.print(order[i]+"\t");if((i+1)%10==0){System.out.println();}}List<Integer> pageSeq = pageSeq(order); //依次存放着指令所在的页面号List<Integer> memoryNum= new ArrayList<Integer>(4);//内存块存储的页面int count=0;//记录缺页次数for(int i=0;i<320;i++){int page = order[i]/10;if(memoryNum.contains(page)) //若该指令所在页面已经在内存,输出该页面所在内存块的号{}else//没在内存,发生缺页,需要判断内存块是否存满,{if(memoryNum.size()<4) //内存没满,直接将所需页面调入内存{memoryNum.add(page);}else//内存存满,需要调用页面置换算法,进行页面置换{OptimalChangePage(pageSeq,i+1,memoryNum,page);//最佳置换算法}count++;//记录缺页次数}printList(memoryNum);//打印内存所调入页面的情况}System.out.println("缺页率:"+(double)count/320);}}package mainDart;import java.util.ArrayList;import java.util.List;public class TestAPP {public static void main(String[] args) {List<Integer> list = new ArrayList<Integer>();list.add(1);list.add(3);list.add(45);System.out.println(list);list.remove(1);list.add(1, -1);System.out.println(list);}}。
操作系统-请求页式存储管理实验报告操作系统实验三存储管理实验班级:学号:姓名:⽬录1. 实验⽬的 (2)2. 实验内容 (2)(1) 通过随机数产⽣⼀个指令序列,共320条指令 (2)(2) 将指令序列变换成为页地址流 (2)(3) 计算并输出下述各种算法在不同内存容量下的命中率 (2)3. 随机数产⽣办法 (3)环境说明 (3)4. 程序设计说明 (3)4.1.全局变量 (3)4.2.随机指令序列的产⽣ (4)4.3.FIFO算法 (4)4.4.LRU算法 (4)4.5.OPT算法 (5)5. 编程实现(源程序): (5)6. 运⾏结果及分析 (11)6.1.运⾏(以某两次运⾏结果为例,列表如下:) (11)6.2.Belady’s anomaly (11)1.实验⽬的存储管理的主要功能之⼀是合理地分配空间。
请求页式管理是⼀种常⽤的虚拟存储管理技术。
本实验的⽬的是通过请求页式存储管理中页⾯置换算法模拟设计,了解虚拟存储技术的特点,掌握请求页式存储管理的页⾯置换算法。
2.实验内容(1) 通过随机数产⽣⼀个指令序列,共320条指令指令的地址按下述原则⽣成:a) 50% 的指令是顺序执⾏的;b) 25% 的指令是均匀分布在前地址部分;具体的实施⽅法是:a) 在[0,319]的指令地址之间随机选取⼀起点m;b) 顺序执⾏⼀条指令,即执⾏地址为m+1的指令;c) 在前地址[0,m+1]中随机选取⼀条指令并执⾏,该指令的地址为m';d) 顺序执⾏⼀条指令,其地址为m'+1;e) 在后地址[m'+2,319]中随机选取⼀条指令并执⾏;f) 重复上述步骤a)~f),直到执⾏320次指令。
(2) 将指令序列变换成为页地址流设:a) 页⾯⼤⼩为1K;b) ⽤户内存容量为4页到32页;c) ⽤户虚存容量为32K。
在⽤户虚存中,按每K存放10条指令排列虚存地址,即320条指令在虚存中的存放⽅式为:第0条~第9条指令为第0页(对应虚存地址为[0,9]);第10条~第19条指令为第1页(对应虚存地址为[10,19]);……第310条~第319条指令为第31页(对应虚存地址为[310,319])。
请求分页式存储管理
为简单起见。
页面淘汰算法采用 FIFO 页面淘汰算法, 只将该页在页表中修改状态位。
而不再判断它是否被改写过, 也不
将它
输入进程大小(例如 5300bytes ),对页表进行初始化
系统为进程分配3个物理块(页框),块号分别为0、1、2,页框管理表(空闲块表)
任意输入一个需要访问的指令地址流(例如:
4355,输入负数结束),打印页表情况。
每访问一个地址时, 首先要计算该地址所在的页的页号, 然后查页表,判断该页是否在
主存 ——如果该页已在主存,则打印页表情况;如果该页不在主存且页框未满 (查空闲块表, 找到空闲块),则调入该页并修改页表,打印页表情况;如果该页不在主存且页框已满,则 按FIFO 页面淘汰算法淘汰一页后调入所需的页,修改页表,打印页表情况。
存储管理算法的流程图见下页。
三、实验要求
完成实验内容并写出实验报告,报告应具有以下内容:
1、 实验目的。
2、 实验内容。
3、 程序及运行情况。
4、 实验过程中出现的问题及解决方法。
#in clude<stdio.h>
#in clude<stdlib.h> int P UB[20][3];
int ABC[3][2]={{0,1},{1,1},{2,1}};// 物理块 int key=0;
一、 问题描述
设计一个请求页式存储管理方案, 并且在淘汰一页时, 写回到辅存。
二、 基本要求 页面尺寸1K , 页表结
构如下:
3635、 3642、 1140、 0087、 1700、 5200、
void output(int size){
//打印int i,j;
printf(”页号\t\t物理块号\t\t状态位\n\n");
for(i=0;i<size;i++)
{
printf(" %d\t\t%d\t\t\t%d\n\n",PUB[i][0],PUB[i][1],PUB[i][2]); }
printf(" 物理块号\t\t 是否空闲\n\n"); for(i=0;i<3;i++)
{
printf(" %d\t\t\t%d\n\n",ABC[i][0],ABC[i][1]);
}
}
void main(){ int size; int i,j; int address=0; int select=0;
printf(" 请输入进程大小\n"); scanf("%d",&size); if(size<=0 || size>20000) { printf(" 进程大小超出范围\n"); exit(0);
}
size%1000==0 ? size=size/1000 : size=size/1000+1;
for(i=0;i<size;i++) {
PUB[i][0]=i;
PUB[i][1]=0;
PUB[i][2]=0; } output(size);
while(1)
{//页号//物理块号//状态位
printf(" 输入指令地址\n"); scanf("%d",&address); if(address<0 || address>20000) { printf(" 地址超出范围\n");
exit(0);
}
address%1000==0 ? address=address/1000 : address=address/1000;
if(PUB[address][2]==0) // 不在主存{
if(ABC[2][1]==0)
//满了
{
printf(" 满了\n");
key++;
if(select!=address)
for(i=0;i<size;i++)
{
if(PUB[i][1]==key) {
PUB[i][1]=0;
PUB[i][2]=0;
}
}
PUB[address][1]=key;
PUB[address][2]=1; key++;
if(key>3) key=1;
}
if(ABC[2][1]==1)
//没满
{
printf(" 没满
\n");
for(i=0;i<3;i++)
{
if(ABC[i][1]==1)
{
ABC[i][1]=0;
PUB[address][1]=i+1;
PUB[address][2]=1;
break;
}
}
} output(size);
} }} else
{
printf(" 该页已在内存\n"); output(size); } select=address;。