操作系统实验——分页式存储管理

二、分页式存储器管理

目录

2.1目的

2.2内容

2.3实验提示

2.4数据结构

2.5算法设计及流程图 

2.6 运行截图

2.7 小结

2.8代码


2.1目的

  1. 熟练掌握分页式管理基本原理,并在实验过程中体现内存空间的分配回收、地址转换过程。
  2. 掌握利用位示图管理内存与置换空间的分配与回收。
  3. 掌握基本的位运算
  4. 掌握请求式分页存储管理基本原理,并在试验过程中体会内存与置换空间的分配与回收、地址转换以及缺页处理过程。

2.2内容

在实验一的基础上实现分页式存储管理内存分配和地址转换过程。进一步实现请求分页式存储管理过程,包括内存和置换空间管理、地址转换以及缺页处理,能够体现FIFO和LRU算法思想。

2.3实验提示

1.建立一个位示图数据结构,用来模拟内存的使用情况。位示图是利用若干位的0/1值代表某类空间的占用状态的数据结构。在本实验中,位示图的位数与设定的物理块个数相同。程序启动时可利用一组随机0或1填充位示图,以模拟程序开始执行是内存已被占用状态。

假设内存大小为64K,块大小为1K,则共有64个块,需要创建如下的位示图数据结构:

#define BLOCK_SIZE 1024 //块大小,定义成宏,便于修改

#define MEM_SIZE 64 //块个数

//定义char型数组,每个char变量占用8位,长度为8,共64位

char bitmap[MEM_SIZE/8];

随机填充的代码如下:

#include "time.h"

srand(time(NULL));

for(i=0;i<MEM_SIZE/8;i++)

…bitmap[i]=(char)rand();

随机填充后的位示图可能的值如图2-1所示。该位示图表示内存的2(0字节第2位)、3(0字节第3位)、6(0字节第6位)、8(1字节第0位)、9(1字节第1位)、12(1字节第4位)、15(1字节第7位)…等块没有被占用。

 

图2-1 具有随机值的位示图示例

2. 在实验1基础上扩充PCB,添加进程大小和页表:

struct PCB{

int size;

int* page_table;

创建进程时输入进程大小,并根据程序中设定的页面大小为进程分配页表空间,并分配物理块。例如,在上图基础上,若要建立一个大小为5000字节的进程,则

  1. 计算该进程共有“向上取整(5000/1024)=5”个页,需要占用5个内存块;
  2. 建立空的页表,即长度为5的一维整数数组;
  3. 从位示图中找出前5个“0”位在整个位示图中的位置号(即内存中的空闲块块号)(若第i字节第j位为0,则该位在位示图中的位置为8*i+j),并将这些位置号依次填入页表中,同时把对应的“0”改为“1”,以示对应内存块已经分配。

tmp=(struct PCB *)malloc(sizeof(struct PCB));//所创建进程的PCB

tmp->size=size;//进程大小

//计算出块个数

block_count=(int)ceil(tmp->size/(double)BLOCK_SIZE); //分配页表

tmp->page_table=(int *)malloc(sizeof(int)*block_count);

在位示图中判断某字节b的第bit_no位是1还是0代码如下:

int getbit(char b,int bit_no){   

   //将00000001左移bit_no位,得到如00010000值

   char mask=(char)1<<bit_no;

   if(b&mask) //进行与操作后结果不为0,则第bit_no位一定是1

      return 1;

   else//进行与操作后结果为0,则第bit_no位一定是0

      return 0;

}

设置位示图的某字节b的第bit_no位为1或0代码如下:

void setbit(char *b,int bit_no,int flag){

   char mask=(char)1<<bit_no;//得到如00010000值

   if(flag)//flag为真,表示将第bit_no位设置为1

      *b=*b|mask;//进行或操作,对应位变成1

   else{//flag为假,表示将第bit_no位设置为0

      mask=~mask;//取反,得到如11101111值

      *b=*b&mask;//进行与操作,对应位变成0

   }

}

3. 输入当前执行进程所要访问的逻辑地址,并将其转换成相应的物理地址:

(1)首先编写根据页面大小得到逻辑地址中页号和页内地址分界值(如页面大小为1024,则分界值为log21024=10)

int mylog2(int size){//size为页面大小   

   return (int)ceil((log10(size)/log10(2)));

}

(2)根据输入的逻辑地址la,计算其页号和页内地址:

int la,pageno,offset,mask;

printf("逻辑地址:(<0退出)");

scanf("%d",&la);

//将逻辑地址右移若干位,得到页号

pageno=la>>mylog2(BLOCK_SIZE);

//将1111…111左移若干位,得到11…11000..00

mask=(0xffffffff)<<mylog2(BLOCK_SIZE);

//将11…11000..00取反,得到00…00111..11

mask=~mask;

//将逻辑地址与mask进行与操作,得到页内地址

offset=la&mask;

  1. 进程退出时,根据其页表内容将位示图对应位置的“1”回填为“0”。
  2. 扩充页表,将其变成支持请求和置换功能的二维页表(增加存在位等)。创建进程时可装入固定的前三页(或键盘输入初始装入页数,不同进程的装入个数可以不同),其余页装入到置换空间内(置换空间大小应为内存空间大小的1.5-2倍,对其还需建立独立的置换空间位示图)。
  3. 分别采用FIFO或LRU置换算法对地址转换过程中可能遇到的缺页现象进行页面置换。可将多次地址转换过程中所涉及到的页号视为进程的页面访问序列,从而计算置换次数和缺页率。以下是某次地址变换过程中的交互示例(红色为用户输入,蓝色为程序提示):

逻辑地址:3072

是否为写指令(Y/N):Y

逻辑地址3072对应的页号为:3,页内偏移地址为:0

3号页不在内存,外存块号为12,需置换

   利用FIFO算法选中内存1号页,该页内存块号为6,修改位为1,外存块号为10

   将内存6号块内容写入外存10号块,成功

   将外存12号块内容调入内存6号块中,置换完毕

逻辑地址3072对应的物理地址为6144

2.4数据结构

结构体、链表、一维数组

2.5算法设计及流程图 

2.6 运行截图

 

2.7 小结

功能基本实现,调试成功,没警告,没错误。

通过实验更加了解了页面置换算法的基本流程,能够解决相关问题

2.8代码

#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<time.h>
#include<stdlib.h>
#define block_size 1024//块大小
#define mem_size 64//内存大小
#define swapspace_size 128//置换空间大小
#define lode_count 3//进程最多装入页数
#define maxsize 10//最大页表空间
int bitmap[64];
int swapbitmap[128];
using namespace std;
typedef struct Page_table//页表
{
	int pageno,blockno,swapspaceno;//页号,块号,置换块号
	int exists;//存在位,
}page_table[maxsize];
typedef struct PCB
{
	int name;
	int sizes;    //进程大小
	page_table pt;//一个进程的页表
	int length;//当前页表个数
	int fifo[3],lru[3],opt[3];
	int optlist[maxsize];
	int fifon,lrun,listn;//fifo,lru中页面的个数
	double absent1,absent2,absent3;
	double visit1,visit2;
	struct PCB *next;
}PCB,*PCBlist;
PCBlist running;
void createbitmap()//创建位视图
{
	int i;
	srand(time(NULL));
	for(i=0;i<mem_size;i++)
		bitmap[i]=(rand()%2);
    for(i=0;i<swapspace_size;i++)
		swapbitmap[i]=(rand()%2);
}
void showbitmap()//显示位视图
{
	cout<<"位示图"<<endl;
	int i;
	for(i=0;i<mem_size;i++)
	{
		cout<<bitmap[i];
		if((i+1)%8==0)
			cout<<endl;
	}
	cout<<"置换空间位示图"<<endl;
	for(i=0;i<swapspace_size;i++)
	{
		cout<<swapbitmap[i];
		if((i+1)%16==0)
			cout<<endl;
	}
}
void initpagetable(PCBlist &s)//初始化页表
{
     PCBlist p;
    p=s->next;
	int i,j;
        for(i=0;i<maxsize;i++)
        {
            p->pt[i].pageno=-1;
            p->pt[i].blockno=-1;
            p->pt[i].swapspaceno=-1;
            p->pt[i].exists=0;
        }
        for(j=0;j<lode_count;j++)
        {
            p->fifo[j]=-1;
            p->lru[j]=-1;
            p->opt[j]=-1;
        }
}
void createpage(PCBlist &s)//创建页表
{
    PCBlist p;
    p=s->next;
	int m;
	int i,j=0,k=0,t=0;
	m= (int)ceil((double)p->sizes/(double)block_size);
	p->length=m;
	p->listn=p->fifon=p->lrun=0;
	p->absent1=p->absent2=p->absent3=0;
	p->visit1=p->visit2=0;
	if(m<=lode_count)
	{
		for(i=0;i<m;i++)//内存,页表 赋值
		{
			while((bitmap[j]!=0))//找位示图中的空闲内存
			{
				j++;
			}
			bitmap[j]=1;
			p->pt[i].pageno=i;
			p->pt[i].blockno=j;//j记录位置
			p->pt[i].exists=1;
		}
		cout<<"该进程的页表如下:"<<endl;
		cout<<"页号\t\t块号\t\t存在位\t\t置换块号"<<endl;
		for(i=0;i<m;i++)//页表显示
		{
			cout<<p->pt[i].pageno<<'\t'<<'\t';
			cout<<p->pt[i].blockno<<'\t'<<'\t';
			cout<<p->pt[i].exists<<'\t'<<'\t';
			cout<<p->pt[i].swapspaceno;
			cout<<endl;
		}

	}
	else
	{
		for(i=0;i<lode_count;i++)
		{
			while(bitmap[k]!=0)//找位示图中的空闲内存
			{
				k++;
			}
			bitmap[k]=1;//修改位示图
			p->pt[i].pageno=i;
			p->pt[i].blockno=k;
			p->pt[i].exists=1;
		}
		cout<<"该进程的页表如下:"<<endl;
		cout<<"页号\t\t块号\t\t存在位\t\t置换块号"<<endl;
		for(i=0;i<lode_count;i++)
		{
			cout<<p->pt[i].pageno<<'\t'<<'\t';
			cout<<p->pt[i].blockno<<'\t'<<'\t';
			cout<<p->pt[i].exists<<'\t'<<'\t';
			cout<<p->pt[i].swapspaceno;
			cout<<endl;
		}
		for(i=lode_count;i<m;i++)//将不在内存的页存放在置换空间内
		{
			while(swapbitmap[t]!=0)//t是外存块号,i是页号
			{
				t++;
			}
			swapbitmap[t]=1;
			p->pt[i].swapspaceno=t;
			p->pt[i].pageno=i;
		}
		cout<<"该进程在置换空间的页表如下:"<<endl;
		cout<<"页号\t\t块号\t\t存在位\t\t置换块号"<<endl;
		for(i=lode_count;i<m;i++)
		{
			cout<<p->pt[i].pageno<<'\t'<<'\t';
			cout<<p->pt[i].blockno<<'\t'<<'\t';
			cout<<p->pt[i].exists<<'\t'<<'\t';
			cout<<p->pt[i].swapspaceno;
			cout<<endl;
		}
	}
}
void operateadress(PCBlist s)//计算物理地址
{
    PCBlist p;
    p=s->next;
	cout<<"输入逻辑地址"<<endl;
	int a,b,c,d;
	cin>>a;
	b=a/block_size;//计算页号
	c=a%block_size;//计算页内偏移
	d=p->length;
	if(b>d-1)//页号是否大于页表长度
        cout<<"本次中断,发生越界错误\n";
    else
    {
        if(b>=lode_count)
        {
            cout<<"不在内存中"<<endl;
            cout<<"地址为:"<<(p->pt[b].swapspaceno)*(block_size)+c<<'\t'<<"块号是 "<<p->pt[b].swapspaceno<<"号"<<'\t'<<'\t'<<"在第"<<(p->pt[b].swapspaceno)/8<<"行"<<'\t'<<"第"<<(p->pt[b].swapspaceno)%8<<"列"<<'\t'<<"偏移量为"<<c<<endl;
        }
        else
        {
             cout<<"在内存中"<<endl;
             cout<<"地址为:"<<(p->pt[b].blockno)*(block_size)+c<<'\t'<<"块号是"<<p->pt[b].blockno<<"号"<<'\t'<<'\t'<<"在第"<<(p->pt[b].blockno)/8<<"行"<<'\t'<<"第"<<(p->pt[b].blockno)%8<<"列"<<'\t'<<"偏移量为"<<c<<endl;
        }
    }

}

void pcbover(PCBlist s)
{
    PCBlist p;
    p=s->next;
	cout<<"进程结束后的位示图"<<endl;
	int i,j;
	for(i=0;i<3;i++)
	{
		if(p->pt[i].blockno>=0)
			bitmap[p->pt[i].blockno]=0;
	}
	for(j=3;j<=p->length;j++)
	{
		if(p->pt[j].swapspaceno>=0)
			swapbitmap[p->pt[j].swapspaceno]=0;
	}
	showbitmap();
}
int findplace(int x,PCBlist p)//查找页面在页表中的位置
{
    int i;
    for(i=0;i<=p->length;i++)
        if(p->pt[i].pageno==x)
        return i;
    return -1;
}


void FIFO(PCBlist s)
{

    PCBlist p;
    p=s->next;
	int i,j,k,a,b,c,d,x,y,z,temp1,temp2;
	p->visit1++;
	cout<<"请输入逻辑地址"<<endl;
	cin>>a;
	b=a/block_size;//页号
    /*for(c=0;c<=p->length;i++)
        if(p->pt[c].pageno==b)
            break;*/
	c=findplace(b,p);//查找页号在页表中的位置
	p->optlist[p->listn]=b;//将页面存在总的页面序列中,为opt做准备
	p->listn++;
	if(a>p->sizes)
        cout<<"发生越界错误"<<endl;
    else
    {
        for(i=0;i<3;i++)
            if(b==p->fifo[i])
                break;
        z=i;
		if(z!=3)//页面在队列中
        {
            cout<<"不缺页"<<endl;
            for(i=0;i<3;i++)
            {
                if(p->fifo[i]!=-1)
                    cout<<p->fifo[i]<<" ";
            }

            cout<<endl;
        }
		else
		{   p->absent1++;
			if(p->fifon<3)//队列未满
			{
				if(p->pt[c].exists==1)//所缺页面在内存中
                {
                    p->fifo[p->fifon]=p->pt[c].pageno;
                    for(k=0;k<3;k++)
                    {
                        if(p->fifo[k]!=-1)
                            cout<<p->fifo[k]<<" ";
                    }
                    (p->fifon)++;
                    cout<<endl;
                }
                else
                {
                    for(j=0;j<lode_count;j++)//寻找不在队列里的的页面作为要交换的页面;
                        if(  (p->pt[j].pageno!=p->fifo[0])&&(p->pt[j].pageno!=p->fifo[1])&&(p->pt[j].pageno!=p->fifo[3]))
                        break;
                    d=j;
                    p->fifo[p->fifon]=p->pt[c].pageno;
                    temp1=p->pt[d].pageno;//交换页号
                    p->pt[d].pageno=p->pt[c].pageno;
                    p->pt[c].pageno=temp1;
                    for(k=0;k<3;k++)
                    {
                        if(p->fifo[k]!=-1)
                            cout<<p->fifo[k]<<" ";
                    }

                    (p->fifon)++;
                    cout<<endl;
                    cout<<"内存中没有此页面,从外存中调入的 "<<endl;
                }
			}
			else//队列已满
            {
                if(p->pt[c].exists==1)
                {
                    p->fifo[0]=p->fifo[1];
                    p->fifo[1]=p->fifo[2];
                    p->fifo[2]=p->pt[c].pageno;
                    for(k=0;k<3;k++)
                    {
                        if(p->fifo[k]!=-1)
                            cout<<p->fifo[k]<<" ";
                    }
                    cout<<endl;
                }
                else
                {
                    x=p->fifo[0];
                    p->fifo[0]=p->fifo[1];
                    p->fifo[1]=p->fifo[2];
                    p->fifo[2]=p->pt[c].pageno;
                    y=findplace(x,p);
                    temp2=p->pt[y].pageno;
                    p->pt[y].pageno=p->pt[c].pageno;
                    p->pt[c].pageno=temp2;
                    for(k=0;k<3;k++)
                    {
                        if(p->fifo[k]!=-1)
                            cout<<p->fifo[k]<<" ";
                    }
                    cout<<endl;
                    cout<<"内存中没有此页面,从外存中调入的 "<<endl;
                }
            }
		}
    }
    cout<<"置换次数为:"<<p->absent1<<"次   "<<" 缺页率为:"<<(p->absent1/p->visit1)*100<<"%"<<endl;
}
void LRU(PCBlist s)
{
    PCBlist p;
    p=s->next;
    int i,j,k,a,b,c,d,x,y,z,m,temp1,temp2,temp3,l;//a输入的地址,l判断队列是否存在元素的下标
	p->visit2++;
	cout<<"请输入逻辑地址"<<endl;
	cin>>a;
	b=a/block_size;//页号
	c=findplace(b,p);//查找页号在页表中的位置
	p->optlist[p->listn]=b;//将页面存在总的页面序列中,为opt做准备
	p->listn++;
	if(a>=p->sizes)
        cout<<"发生越界错误"<<endl;
    else
    {
        for(l=0;l<3;l++)//lru队列是否存在此数
            if(b==p->lru[l])
                break;
        z=l;//cout<<z<<endl;
		if(z!=3)//页面在队列中
        {
            cout<<"不缺页"<<endl;
            temp1=p->lru[z];//temp1为存在的那个元素
            if(p->lrun<=2)
			{
				p->lru[z]=p->lru[p->lrun-1];
				p->lru[p->lrun-1]=temp1;

            }
           else
		   {
				for(m=z;m<3;m++)
				  p->lru[m]=p->lru[m+1];
				p->lru[2]=temp1;
            }
           for(i=0;i<3;i++)
           {
                if(p->lru[i]!=-1)
                    cout<<p->lru[i]<<" ";
           }

            cout<<endl;
      }
		else//不再队列中
		{   p->absent2++;//置换次数+1;
			if(p->lrun<3)//队列未满
			{
				if(p->pt[c].exists==1)//所缺页面在内存中
                {
                    p->lru[p->lrun]=p->pt[c].pageno;
                    for(k=0;k<3;k++)//显示
                    {
                        if(p->lru[k]!=-1)
                            cout<<p->lru[k]<<" ";
                    }
                    (p->lrun)++;
                    cout<<endl;
                }
                else//外存中
                {
                    for(j=0;j<lode_count;j++)//寻找队列中第一个空的物理快;
                        if((p->pt[j].pageno!=p->lru[0])&&(p->pt[j].pageno!=p->lru[1])&&(p->pt[j].pageno!=p->lru[2]))
                        break;
                    d=j;
                    p->lru[p->lrun]=p->pt[c].pageno;
                    temp2=p->pt[d].pageno;//交换页号
                    p->pt[d].pageno=p->pt[c].pageno;
                    p->pt[c].pageno=temp2;
                    for(k=0;k<3;k++)
                    {
                        if(p->lru[k]!=-1)
                            cout<<p->lru[k]<<" ";
                    }

                    (p->lrun)++;
                    cout<<endl;
                    cout<<"内存中没有此页面,从外存中调入的 "<<endl;
                }
			}
			else//队列满了
            {
                if(p->pt[c].exists==1)
                {
                    p->lru[0]=p->lru[1];
                    p->lru[1]=p->lru[2];
                    p->lru[2]=p->pt[c].pageno;
                    for(k=0;k<3;k++)
                    {
                        if(p->lru[k]!=-1)
                            cout<<p->lru[k]<<" ";
                    }
                    (p->lrun)++;
                    cout<<endl;
                }
                else
                {
                    x=p->lru[0];
                    p->lru[0]=p->lru[1];
                    p->lru[1]=p->lru[2];
                    p->lru[2]=p->pt[c].pageno;
                    y=findplace(x,p);
                    temp3=p->pt[y].pageno;
                    p->pt[y].pageno=p->pt[c].pageno;
                    p->pt[c].pageno=temp3;
                    for(k=0;k<3;k++)
                    {
                        if(p->lru[k]!=-1)
                            cout<<p->lru[k]<<" ";
                    }
                    (p->lrun)++;
                    cout<<endl;
                    cout<<"内存中没有此页面,从外存中调入的 "<<endl;
                }
            }
		}
    }
     cout<<"置换次数为:"<<p->absent2<<"次   "<<" 缺页率为:"<<(p->absent2/p->visit2)*100<<"%"<<endl;
}
void out(PCBlist p)
{
  while(p->next!=NULL)
    {
       cout<<p->next->name<<" ";
       cout<<p->next->sizes<<" ";
       p=p->next;
    }
  cout<<"\n";
}
void show(PCBlist p)//就绪状态和堵塞状态展示
{
    while(p->next)
	{
		cout<<p->next->name<<" ";
		p=p->next;
	}
}
void runshow(int m)//执行状态展示
{
	if(m==0)
		cout<<"没有正在执行的进程"<<endl;
	else
		cout<<m<<endl;
}
void add(PCBlist &l,int name,int sizes)
{
	PCBlist p=l;
	PCBlist s=new PCB;
	s->name=name;
	s->sizes=sizes;
	s->next=NULL;
	if(p->next==NULL)//进程链为空添加节点
	{
		p->next=s;
	}
	else
	{
		while(p->next!=NULL)//进程链不为空添加节点
		{
			p=p->next;
		}
		p->next=s;
	}
}
void showall(PCBlist p1,PCBlist p2,int m)//进程状态显示
{
	cout<<"就绪状态为:";
	show(p1);
	cout<<endl;
	cout<<"执行状态为:";
	runshow(m);
	cout<<"阻塞状态为:";
	show(p2);
	cout<<endl;
}
int main()
{
	int n,number,c,m=0,j=0,sizes,temp;//m为正在执行的进程标号 n菜单选择 number进程名,sizes进程的大小 c唤醒进程
	PCBlist ready=new PCB;
	ready->next=NULL;
    PCBlist blocked=new PCB;
	blocked->next=NULL;
    running=new PCB;
	running->next=NULL;
	PCBlist pa=ready,pb=blocked,pc=ready,pd=blocked;
	PCBlist p,q;
	while(true)
	{
	    cout<<"欢迎来到我的页式存储管理系统"<<endl;
	    cout<<"1-创建进程"<<endl;
        cout<<"2-时间片到"<<endl;
        cout<<"3-进程阻塞"<<endl;
        cout<<"4-唤醒进程"<<endl;
        cout<<"5-结束进程"<<endl;
        cout<<"6-创建位图"<<endl;
        cout<<"7-创建并显示进程的页表"<<endl;
        cout<<"8-显示位图"<<endl;
        cout<<"9-地址变换"<<endl;
        cout<<"10-LRU算法"<<endl;
        cout<<"11-FIFO算法"<<endl;
        cout<<"13-显示执行进程信息"<<endl;
        cout<<"0-退出"<<endl;
        cout<<"请根据功能输入序号"<<endl;
        cin>>n;
		switch(n)
		{
		case 1://创建进程
			 {
                cout<<"请输入进程名字(用0~9表示):";
                cin>>number;
                cout<<"请输入进程大小:";
                cin>>sizes;
				add(ready,number,sizes);
				if(m==0)//如果还没有正在执行的进程
				{
					if(ready->next!=NULL)//就绪队列不为空
					{
					    add(running,ready->next->name,ready->next->sizes);
						temp=ready->next->name;//获取队头进程(就绪队列第一个元素)
						ready->next=ready->next->next;//将就绪状态变为执行状态
						m=temp;
					}
					showall(ready,blocked,m);
				}
				else
				{
					showall(ready,blocked,m);
				}
				break;
			}
		case 2://时间片到
			{
				if(m!=0)
				{
					add(ready,m,running->next->sizes);//将正在执行的进程添加到就绪状态中
					m=0;running->next=NULL;
					if(ready->next!=NULL)
					{
					    //running->next=ready->next;
					    add(running,ready->next->name,ready->next->sizes);
						temp=ready->next->name;
						ready->next=ready->next->next;
						m=temp;
					}//将此时就绪队列的队头变为执行状态
					showall(ready,blocked,m);
				}
				else
				{
					cout<<"没有正在进行的进程"<<endl;
				}
				break;
			}
		case 3://进程阻塞
			{
				if(m==0)
					cout<<"没有正在进行的进程"<<endl;
				else
				{
					add(blocked,m,running->next->sizes);//将阻塞的进程添加到阻塞队列
					m=0;running->next=NULL;
					if(ready->next!=NULL)
					{
					    add(running,ready->next->name,ready->next->sizes);
						temp=ready->next->name;
						ready->next=ready->next->next;
						m=temp;
					}//将此时就绪队列的队头变为执行状态
					showall(ready,blocked,m);
				}
				break;
			}
		case 4://唤醒进程
			{
				if(blocked->next==NULL)
					cout<<"没有正在阻塞的进程"<<endl;
				else
				{
					cout<<"请输入要唤醒的进程"<<endl;
					cin>>c;
					while(pb->next->name!=c)//找到要唤醒的进程
						pb=pb->next;
					add(ready,pb->next->name,pb->next->sizes);//将要唤醒的进程添加到就绪队列中
					if(pb->next->next!=NULL)
					    pb->next=pb->next->next;
					else
                        pb->next=NULL;
					//showall(ready,blocked,m);
				}
				if(m==0)//如果没有正在执行的进程
				{
					if(ready->next!=NULL)
					{
					    add(running,ready->next->name,ready->next->sizes);
						temp=ready->next->name;
						m=temp;
						ready->next=ready->next->next;
					}
					showall(ready,blocked,m);

				}
				else{
					showall(ready,blocked,m);
				}
				break;
			}
		case 5://结束进程
			{
			       pcbover(running);
					m=0;running->next=NULL;
					if(ready->next!=NULL)
					{
					    add(running,ready->next->name,ready->next->sizes);
					    //out(ready);
						temp=ready->next->name;
						ready->next=ready->next->next;
						m=temp;
					}
					showall(ready,blocked,m);
				break;
			}
         case 6:createbitmap();showbitmap();break;

         case 7:
             {
                 initpagetable(running);
                 p=running->next;
                 if(p->pt[0].pageno!=-1)
                    cout<<"页表已经创建"<<endl;
                 else
                 {
                     initpagetable(running);
                     createpage(running); break;
                 }
                 break;
             }
         case 8:showbitmap();break;

         case 9:operateadress(running);break;

         case 10:LRU(running);break;

         case 11:FIFO(running);break;

         case 13:out(running);
             break;

         case 0:exit(0);
		}
	}
	return 0;
}

  • 26
    点赞
  • 189
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
### 回答1: 分页存储管理是操作系统中一种常见的内存管理方,它将进程的逻辑地址空间划分为固定大小的页,将物理内存划分为与之相等的物理页框,通过页表实现逻辑页与物理页之间的映射关系。在实验中,我们可以使用Java编程语言模拟分页存储管理的过程。 首先,我们需要定义一个页表类,用于记录逻辑页号和物理页号之间的映射关系。该类可以包含一个哈希表或数组,以逻辑页号作为键,物理页号作为值。 接下来,需要编写一个模拟程序,模拟进程的内存访问过程。该程序可以随机生成一个逻辑地址,然后通过页表查找该逻辑地址对应的物理页号。如果页表中存在该逻辑页号的映射关系,程序就可以通过物理页号找到相应的物理内存地址;否则,程序需要进行页面置换算法来选择一个物理页进行替换,并更新页表中的映射关系。 在实验中,可以选择常见的页面置换算法,如最近最久未使用(LRU)、先进先出(FIFO)、钟算法(CLOCK)等,来模拟操作系统的页面置换过程。根据选择的算法,我们可以编写相应的替换函数来实现物理页的选择和替换。 总之,通过实现一个页表类和模拟程序,我们可以模拟分页存储管理的过程,并通过选择适当的页面置换算法来实现页的替换操作。该实验可以帮助我们更好地理解操作系统中的内存管理机制,并加深对分页存储管理的理解。 ### 回答2: 操作系统分页存储管理是计算机操作系统中的一个重要概念,它涉及到内存中数据的存储和管理。在分页存储管理中,内存被划分为固定大小的页框,每个页面大小相同。而程序的数据则被划分为多个大小相等的页面,每个页面被映射到内存中的一个页框。通过这种方,程序的逻辑地址可以被划分为页号和偏移量,而不需要关心实际的物理地址。 在这个实验中,我们可以用Java编写一个简化的分页存储管理系统模拟。我们可以通过以下几个步骤来完成这个实验: 1. 定义页面和页框的大小。例如,我们可以将页面和页框大小都定义为4KB,即4096字节。 2. 定义程序的逻辑地址空间和物理地址空间。逻辑地址空间可以分为页号和偏移量,而物理地址空间则直接对应着内存中的页框。 3. 实现页面的映射和置换算法页面的映射可以通过一个页表来实现,存储页面到页框的映射关系。如果内存中的页框已经被占用,需要使用置换算法将某些页面置换出去,腾出页框给新的页面。 4. 实现页面访问和管理功能。通过逻辑地址,我们可以找到对应的页号和偏移量,然后根据页表的映射关系找到物理地址。页面的访问可以是读取或写入操作。 通过这个实验,我们可以深入理解分页存储管理的原理并且学习如何使用Java来模拟实现这个功能。这有助于我们更好地理解操作系统中内存的管理和存储机制。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

二琳爱吃肉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值