fifo先进先出c语言算法

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

#include
#include

#define RAM 8*1024 //在内存中分配的模拟内存大小以k为单位
#define EXTERNALSTROE 25*1024 //在内存中分配的模拟外存大小
#define PAGELENGTH 512 //页面大小
#define PAGENUM 4 //内存中为每个内存分配的页面
#define MAXSTEP 100//调度顺序中最多能调度的页数
#define p1Name 'A' //进程名字
#define p2Name 'B'
#define p3Name 'C'
#define p1Length 4.2*1024
#define p2Length 8*1024
#define p3Length 9.8*1024

//fifo队列
typedef struct QNode{
int addr;//存储在外存中的地址
struct QNode *next;
}QNode,*QueuePtr;
//lru结构体
typedef struct Page{
int addr;
int time;
}Page;
//nur的循环队列
typedef struct CNode{
int pageNo;//在外存中的地址
int callNo;//访问号0~1
struct CNode *next;
}CNode,*CLinkList;

//进程信息结构体
typedef struct PROCESS{
char name;
int lengeth; //进程大小
int size; //进程给定的页面大小可分为的页面数
int start; //进程在外存中的起始地址
int end;//进程在外存中的终止地址
int step;
int stepNow;//当前已调度了的页数
int controlSequ[MAXSTEP]; //保存进程调度顺序
int detail[MAXSTEP][PAGENUM];//记录页面置换过程
int occupyNum;//已占用的内存块数
int count; //缺页次数
float page_fault_rate;//缺页率
int m;//置换次数
float replacement_rate;//置换率
Page *page[PAGENUM];
QNode *front;
QNode *rear;
CNode *head;

int opage[PAGENUM];
}PROCESS;

QueuePtr p;

PROCESS pro1,pro2,pro3;
int step; //置换过程中的总的页数
int rSize; //内存按给定的页面大小可为程序分配的总的页数
int eSize; //外存按给定的页面大小可为程序分配的总的页数
int controlSequ[MAXSTEP]; //保存所有进程调度顺序
int position[PAGENUM][2];//用于存储内存中已调入的页面的值与
//即将调入的值相等的opage与controlSequ的下标

void InitQueue(PROCESS *Q);
void InitArr(PROCESS *pro);
void InitList(PROCESS *Q);
void printLine();
/**
初始化PROCESS
*/
void initPro(PROCESS *pro)
{
int i,j;
pro->size=pro->lengeth / PAGELENGTH;
pro->m=0;
pro->step=0;
pro->end=pro->start + pro->size - 1;
pro->stepNow=0;
pro->page_fault_rate=0;
pro->replacement_rate=0;
for(i=0;i{
pro->controlSequ[i]=0;
}
pro->count=0;
for(i=0;i{
for(j=0;j{
pro->detail[i][j]=0;
}
}
}

/*
初始化
*/
void init()
{
rSize=RAM/PAGELENGTH;
eSize=EXTERNALSTROE/PAGELENGTH;
//初始化进程信息
pro1.start=1;
=p1Name;
pro1.lengeth=(int)p1Length;
initPro(&pro1);

pro2.start=pro1.end + 1;
=p2Name;
pro2.lengeth=(int)p2Length;
initPro(&pro2);

pro3.start=pro2.end + 1;
=p3Name;
pro3.lengeth=(int)p3Length;
initPro(&pro3);

InitQueue(&pro1);
InitQueue(&pro2);
InitQueue

(&pro3);

InitArr(&pro1);
InitArr(&pro2);
InitArr(&pro3);

InitList(&pro1);
InitList(&pro2);
InitList(&pro3);

}

/**
输出调度顺序函数
*/
void printSequ()
{
int i;
printf("调度顺序为:\n");
for(i=0;i{
printf("%d ",controlSequ[i]);
}
printf("\n");
printf("调度序列的页面数为:%d\n",step);
printLine();
}

/**
从控制台得到页面调度顺序及相关内容
*/
void getSequ()
{
//printf("请按进程在调度过程中的页面数:(中间用空格隔开)");
//scanf("%d",&);
int i=0;
int value;
printf("请输入页面调度顺序:(1~44之间的数中间用空格隔开,输入其他并回车表示输入完毕)\n");
do{
scanf("%d ",&value);
controlSequ[i]=value;
i++;
step++;
}while(value<45 && value>0);
step=step--;
printLine();
printSequ();

}

void destroySequ()
{
int i;
step=0;
for(i=0;i{
controlSequ[i]=0;
}

}

/**
判断调度序列中的各页面分别是哪个进程的
并分别存储到各自的序列数组中
*/
int classifyPageDetail(int pageValue)
{
if(pageValue<=pro1.end && pageValue>=1)
{ //是进程A的页面
pro1.controlSequ[step]=pageValue;
pro1.step++;
return 1;
}else
if(pageValue<=pro2.end && pageValue>=pro2.start)
{ //是进程B的页面
pro2.controlSequ[step]=pageValue;
pro2.step++;
return 2;
}else
if(pageValue<=pro3.end && pageValue>=pro3.start)
{ //是进程C的页面
pro3.controlSequ[step]=pageValue;
pro3.step++;
return 3;
}else
return 0;
}


/**
求置换率,缺页率
*/
void getResult(int m1,int m2, int m3)
{
if(pro1.step!=0)
{
pro1.page_fault_rate=pro1.count/((float)pro1.step);
pro1.replacement_rate=m1/((float)pro1.step);
}
if(pro2.step!=0)
{
pro2.replacement_rate=m2/((float)pro2.step);
pro2.page_fault_rate=pro2.count/((float)pro2.step);
}
if(pro3.step!=0)
{
pro3.replacement_rate=m3/((float)pro3.step);
pro3.page_fault_rate=pro3.count/((float)pro3.step);
}
}

/**
FIFO
*/
void InitQueue(PROCESS *Q)
{
Q->front=Q->rear=(QueuePtr) malloc (sizeof(QNode));
Q->front->next=NULL;
Q->rear->next=NULL;
}

void add(int addr,PROCESS *Q)
{
p=(QueuePtr)malloc(sizeof(QNode));
p->addr=addr;
p->next=NULL;
Q->rear->next=p;
Q->rear=p;
}
void del(PROCESS *Q)
{
p=Q->front;
Q->front=p->next;
if(Q->rear==p)
Q->rear=Q->front;
free(p);
}
void destroy1(PROCESS *Q)
{
while(Q->front){
Q->rear=Q->front->next;
free(Q->front);
Q->front=Q->rear;
}
}
void destroyQue()
{
destroy1(&pro1);
destroy1(&pro2);
destroy1(&pro3);
}

int sort(int addr,PROCESS *pro)
{
QNode *q1;
if(pro->front->next!=NULL)
{
int j;
q1=pro->front->next;
for(j=0;jstepNow;j++)
{
if(q1->addr==addr)
{
return 1;
}
if(q1->next!=NULL)
{
q1=q1->next;
}else
{
break;
}
}
}

return 0;
}

void coreOfFifo(int value,PROCESS *pro)
{
QNode *q;
int j;
if(sort(value,pro)!=1)
{
pro->count++;
if(pro->stepNow{
add(value,pro);
pro->stepNow++;
}
else{
pro->m++;
del(pro);
add(value,pro);
}
if(pro->front->next!=NULL)
{
q=pro->front->next;
for(j=0;jstepNow;j++)
{
pro->detail[pro->stepNow][j]=q->addr;
printf("%d ",pro->detail[pro->stepNow][j]);
if(q->next!=NULL)
{
q=q->next;
}else
{
break;
}
}
}
}else{
printf("");
}
}


void fifo()
{
int flag;//用于指定页面属于的进程1 A 2 B 3 C
int i;
printf("页面置换过程:\n");
for(i=0;i{
int m=controlSequ[i];
flag=classifyPageDetail(m);
switch(flag)
{
case 1:
printf("\n A:");
coreOfFifo(m,&pro1);
break;
case 2:
printf("\n B:");
coreOfFifo(m,&pro2);
break;
case 3:
printf("\n C:");
coreOfFifo(m,&pro3);
break;
}
}
getResult(pro1.m, pro2.m, pro3.m);
}


/**
LRU
*/
void InitArr(PROCESS *pro)
{
int i;
for(i=0;i{
pro->page[i]=(Page *)malloc(sizeof(Page));
}
}
int sort2(int value,PROCESS *pro)
{
int i;
for(i=0;istepNow;i++)
{
if(pro->page[i]!=NULL && (pro->page[i])->addr==value)
{
return i;
}
}
return -1;
}
void add2(int value,PROCESS *pro)
{
int m;
m=pro->stepNow;
pro->page[m]->addr=value;
pro->page[m]->time=0;
}
void update2(int value,PROCESS *pro)
{
int i,j;
int max=0;
for(i=0;i{
if((pro->page[i])->time>max)
{
max=(pro->page[i])->time;
j=i;
}
}
pro->page[j]->addr=value;
pro->page[j]->time=0;

}
void destroy2(PROCESS *pro)
{
int i;
for(i=0;istepNow;i++)
{
free(pro->page[i]);
}
}
void destroyArr()
{
if(pro1.page[0]!=NULL)
destroy2(&pro1);
if(pro2.page[0]!=NULL)
destroy2(&pro2);
if(pro3.page[0]!=NULL)
destroy2(&pro3);
}
void coreOfLru(int value,PROCESS *pro)
{
int j,k;
if(sort2(value,pro)<0)
{
pro->count++;
if(pro->stepNow{
add2(value,pro);
pro->stepNow++;
}
else{
pro->m++;
update2(value,pro);
}
if(pro->page[0]!=NULL)
{
for(j=0;jstepNow;j++)
{
pro->detail[pro->stepNow][j]=pro->page[j]->addr;
printf("%d ",pro->detail[pro->stepNow][j]);
}

}
}else{
int n=sort2(value,pro);
pro->page[n]->time=0;
}
for(k=0;k{
pro->page[k]->time++;
}
}
void lru()
{
int flag;//用于指定页面属于的进程1 A 2 B 3 C
int i;

printf("页面置换过程:\n");
for(i=0;i{
int m=controlSequ[i];

flag=classifyPageDetail(m);
switch(flag)
{
case 1:

printf("\n A:");
coreOfLru(m,&pro1);
break;
case 2:
printf("\n B:");
coreOfLru(m,&pro2);
break;
case 3:
printf("\n C:");
coreOfLru(m,&pro3);
break;
}
}
ge

tResult(pro1.m, pro2.m, pro3.m);
}




/**
NUR
*/
void InitList(PROCESS *Q)
{
Q->head=(CLinkList) malloc (sizeof(CNode));
Q->head->next=Q->head;

}

void addList(int addr,PROCESS *Q)
{
CLinkList c;
CLinkList p;//用于头指针与插入指针位置的调换

if(Q->head->pageNo<0)
{
Q->head->pageNo=addr;
// Q->head->blockNo=1;
Q->head->callNo=0;
}else
{
c=(CLinkList) malloc (sizeof(CNode));
c->pageNo=addr;c->callNo=0;//c->blockNo=Q->head->blockNo+1;
c->next=Q->head->next;
Q->head->next=c;
p=c;c=Q->head;Q->head=p;
}
}
void dellist(PROCESS *Q)//no为将要删除的节点在那个位置
{
CLinkList c;
CLinkList p;
CLinkList q;
p=(CLinkList) malloc (sizeof(CNode));
c=Q->head->next;
q=Q->head->next;
while(c!=Q->head && c->pageNo!=0)//找到要删除的节点
{
if(c->callNo==0)
{
p=c;
break;
}else
{
c->callNo=0;
}
c=c->next;
}
while(q!=Q->head && q->pageNo!=0)//找到要删除节点的前一个位置
{
if(q->next==p)
{
break;
}else
{
q=q->next;
}
}
q->next=q->next->next;
free(p);

}

void destroy3(PROCESS *Q)
{
CLinkList p;
p=(CLinkList) malloc (sizeof(CNode));
while(Q->head->pageNo>0){
p=Q->head->next;
free(Q->head);
if(p!=NULL)
Q->head=p;
}
}
void destroyList()
{
destroy3(&pro1);
destroy3(&pro2);
destroy3(&pro3);
}


int sort3(int addr,PROCESS *pro)
{
CNode *q1;
if(pro->head->pageNo!=0)
{
int j;
q1=pro->head->next;
for(j=0;jstepNow;j++)
{
if(q1->pageNo==addr)
{
q1->callNo=1;//将被访问的访问位置为1
return 1;
}
if(q1->next!=NULL)
{
q1=q1->next;
}else
{
break;
}
}
}
return 0;
}

void coreOfNru(int value,PROCESS *pro)
{
CNode *q;
int j;
if(sort3(value,pro)!=1)
{
pro->count++;
if(pro->stepNow{
addList(value,pro);
pro->stepNow++;
}
else{
pro->m++;
dellist(pro);
addList(value,pro);
}
if(pro->head->next != pro->head && pro->head->pageNo != 0)
{
q=pro->head->next;
for(j=0;jstepNow;j++)
{
pro->detail[pro->stepNow][j]=q->pageNo;
printf("%d ",q->pageNo);
q=q->next;
}
}else{
printf("%d ",pro->head->pageNo);
}
}else{
printf("");
}
}


void nru()
{
int flag;//用于指定页面属于的进程1 A 2 B 3 C
int i;
printf("页面置换过程:\n");
for(i=0;i{
int m=controlSequ[i];
flag=classifyPageDetail(m);
switch(flag)
{
case 1:
printf("\n A:");
coreOfNru(m,&pro1);
break;
case 2:
printf("\n B:");
coreOfNru(m,&pro2);
break;
case 3:
printf("\n C:");
coreOfNru(m,&pro3);
break;
}
}
getResult(pro1.m, pro2.m, pro3.m);
}





/**
Opt
*/
void InitOptArr(PROCESS *pro)
{
int i;
for(i=0;i{
pro->opage[i]=0;
}
}
int sort4(int value,PROCESS *pro)


{
int i;
for(i=0;istepNow;i++)
{
if(pro->opage[i]==value)
{
return i;
}
}
return -1;
}
void add4(int value,PROCESS *pro)
{
int m;
m=pro->stepNow;
pro->opage[m]=value;
}
/**
初始化position【】【】
*/
void initPos()
{
int i;
for(i=0;i{
position[i][0]=100;
position[i][1]=100;
}
}

/**
用于得到内存中已调入的页面的值与
即将调入的值相等的opage与controlSequ的下标并返回相等值的个数
*/
void com(int pos,PROCESS *pro)
{
int i,j;
for(i=0;i{
printf("");
for(j=pos;j{
if(pro->opage[i]==controlSequ[j])
{
position[i][0]=i;
position[i][1]=j;
break;
}
}
}
}

/**
用于得到即将访问的与内存中的页相同的在调度序列中最远的的
*/
int getfurther()
{
int max=0;
int maxI=-1;
int i,count=0;
for(i=0;i{
if(max{
max=position[i][1];
maxI=i;
}
}
if(max==100)//如果将在最久执行的页面有多个时 随机选一个置换出
{
int array[PAGENUM];
for(i=0;i{

if(position[i][1]==100)
{
array[count]=i;
count++;
}
}
if(count>1)
{
int mm;
mm=rand()%(count);
maxI=array[mm];
}
}
initPos();
return maxI;
}

void update4(int value,PROCESS *pro,int pos)
{
int maxI;
initPos();
com(pos,pro);
maxI=getfurther();

if(maxI>=0)
pro->opage[maxI]=value;
else
{//
pro->opage[0]=value;
}

}
/*void destroy4(PROCESS *pro)
{
int i;
for(i=0;istepNow;i++)
{s
pro->opage[i]=0;
}
}*/
void destroyOptArr()
{
InitOptArr(&pro1);
InitOptArr(&pro2);
InitOptArr(&pro3);
}
void coreOfOpt(int value,PROCESS *pro,int pos)
{
int j;
if(sort4(value,pro)<0)
{
pro->count++;
if(pro->stepNow{
add4(value,pro);
pro->stepNow++;
}
else{
pro->m++;
update4(value,pro,pos);
}
if(pro->opage[0]!=0)
{
for(j=0;jstepNow;j++)
{
pro->detail[pro->stepNow][j]=pro->opage[j];
printf("%d ",pro->detail[pro->stepNow][j]);
}

}
}else{

}

}
void opt()
{
int flag;//用于指定页面属于的进程1 A 2 B 3 C
int i;

printf("页面置换过程:\n");
for(i=0;i{
int m=controlSequ[i];

flag=classifyPageDetail(m);
switch(flag)
{
case 1:

printf("\n A:");
coreOfOpt(m,&pro1,i);
break;
case 2:
printf("\n B:");
coreOfOpt(m,&pro2,i);
break;
case 3:
printf("\n C:");
coreOfOpt(m,&pro3,i);
break;
}
}
getResult(pro1.m, pro2.m, pro3.m);
}

/**
打印表格控制线函数
*/
void printLine()
{
printf("\n----------------------------------------------------------\n");
}
void printLine1()
{
printf("\n\t\t ***************\n");
}


/**
进程页面置换过程的打印函数
*/
void print1()
{
printf("进程

名 A B C \n");

printf("\n调度序列的页数 ");
printf("%d页\t\t ",pro1.step);
printf("%d页\t\t\t ",pro2.step);
printf("%d页\t\n",pro3.step);
printf("缺页次数 %d\t\t %d\t\t\t %d\n",pro1.count,pro2.count,pro3.count);
printf("缺页率 %f\t\t %f\t\t %f\n",pro1.page_fault_rate,pro2.page_fault_rate,pro3.page_fault_rate);
printf("置换率 %f\t\t %f\t\t\t %f\n",pro1.replacement_rate,pro2.replacement_rate,pro3.replacement_rate);

}
/**
输出比较信息
*/

void printComInfo()
{
float fpfr1,fpfr2,fpfr3,lpfr1,lpfr2,lpfr3,npfr1,npfr2,npfr3,opfr1,opfr2,opfr3;//缺页率
float fpfr,lpfr,npfr,opfr;//各算法的平均缺页率
fifo();fpfr1=pro1.page_fault_rate;fpfr2=pro2.page_fault_rate;fpfr3=pro3.page_fault_rate;destroyQue();
init();lru();lpfr1=pro1.page_fault_rate;lpfr2=pro2.page_fault_rate;lpfr3=pro3.page_fault_rate;destroyArr();
init();nru();npfr1=pro1.page_fault_rate;npfr2=pro2.page_fault_rate;npfr3=pro3.page_fault_rate;destroyList();
init();opt();opfr1=pro1.page_fault_rate;opfr2=pro2.page_fault_rate;opfr3=pro3.page_fault_rate;destroyOptArr();

//求平均缺页率
fpfr=(fpfr1+fpfr2+fpfr3)/4;
lpfr=(lpfr1+lpfr2+lpfr3)/4;
npfr=(npfr1+npfr2+npfr3)/4;
opfr=(opfr1+opfr2+opfr3)/4;

printLine();
printf("\n* 进程名 A B C 平均\n");
printf(" ______________________________________________________\n");
printf("* fifo的缺页率 %f | %f | %f | %f\n",fpfr1,fpfr2,fpfr3,fpfr);
printf("* lru的缺页率 %f | %f | %f | %f\n",lpfr1,lpfr2,lpfr3,lpfr);
printf("* nru的缺页率 %f | %f | %f | %f\n",npfr1,npfr2,npfr3,npfr);
printf("* opt的缺页率 %f | %f | %f | %f\n\n",opfr1,opfr2,opfr3,opfr);

}
/**
输出主界面
*/
void paintMian()
{
printf("******************************************************************* \n\n");

printf("** 请选择操作: **\n");
printf("\n");
printf("** 1:FIFO算法! **\n");printf("\n");
printf("** 2:LRU算法! **\n");printf("\n");
printf("** 3:NUR算法! **\n");printf("\n");
printf("** 4:OPT算法! **\n");printf("\n");
printf("** 5:比较四种算法! **\n");printf("\n");
printf("** 6:重新输入调度队列! **\n");printf("\n");
printf("** 0:返回到此操作页! **\n");printf("\n");
printf("** 其他任意键退出! **\n");printf("\n");
printf("******************************************************************** \

n");


}

/*
进程页面置换算法的选择函数
*/

void selectType(int controlType)
{
switch(controlType)
{

case 1:printSequ();printf("FIFO算法:\n");fifo();printLine1();print1();printLine();destroyQue();break;
case 2:printSequ();printf("LRU算法:\n");lru();printLine1();print1();printLine();destroyArr();break;
case 3:printSequ();printf("NUR算法:\n");nru();printLine1();print1();printLine();destroyList();break;
case 4:printSequ();printf("OPT算法:\n");opt();printLine1();print1();printLine();destroyOptArr();break;
case 5:printSequ();printComInfo();break;
case 6:destroySequ();getSequ();break;
case 0:paintMian();break;
default:exit(0);break;
}
}

int main()
{
int flag;
int ll=1;
getSequ();
paintMian();
while(ll==1)
{
init();
getchar();
scanf("\n %d",&flag);
selectType(flag);
}
}

相关文档
最新文档