实验三

实验三进程调度模拟程序1.0

一、实验目的

通过本实验可以加深对有关进程控制块、进程队列的概念的进一步理解。

二、实验内容和要求

     1.进程PCB的结构体定义

     2.定义结构体

     3.输入进程序列

     4.排序(按到位时间)

     5.输出进程运行的结果

三、实验方法、步骤及结果测试

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<windows.h>
#include<time.h>

typedef struct node
{
char name[10]; //进程名
int prio; //进程优先数
int cputime; //CPU占用时间
int needtime; //进程到完成还要的时间
int arrivetime; //进程到达时间
int starttime; //进程开始时间
int finishtime; //进程完成时间
int servicetime; //进程服务时间
char state; //进程的状态
struct node *next;
}PCB;

PCB *finish,*ready,*run; //队列指针
int N; //进程量

void firstin()
{
run=ready; //就绪队列头指针赋值给运行头指针
run->state='R'; //进程状态变为运行态
ready=ready->next; //就绪对列头指针后移到下一进程
}


void prt1(char a)
{
switch(a)
{
case 1: /*优先数法*/
printf("名字\tCPU占用时间\t需要的时间\t优先级\t状态\n");break;
case 2: /*先来先服务算法*/
printf("名字\t到达时间\t开始时间\t服务时间\t完成时间\t状态\n");break;
default:break;
}
}


void prt2(char a,PCB *q)
{
switch(a)
{
case 1: printf("%s\t%d\t\t%d\t\t%d\t\t%c\n",q->name,q->cputime,q->needtime,q->prio,q->state);
break;
case 2: printf("%s\t%d\t\t%d\t\t%d\t\t%d\t\t%c\n",q->name,q->arrivetime,q->starttime,q->servicetime,q->finishtime,q->state);
break;
default:break;
}
}


void prt(char algo)
{
PCB *p;
prt1(algo); //输出文字格式
if(run!=NULL) //如果运行指针不空
prt2(algo,run); //输出当前正在运行的PCB
p=ready; //输出就绪队列PCB
while(p!=NULL)
{
prt2(algo,p);
p=p->next;
}
p=finish; //输出完成队列的PCB
while(p!=NULL)
{
prt2(algo,p);
p=p->next;
}
getchar(); //压任意键继续
}


void insert1(PCB *q)
{
PCB *p1,*s,*r;
int b;
s=q; //待插入的PCB指针
p1=ready; //就绪队列头指针
r=p1; //做p1的前驱指针
b=1;
while((p1!=NULL)&&b) //根据优先数确定插入位置
if(p1->prio>=s->prio)
{
r=p1;
p1=p1->next;
}
else
b=0;
if(r!=p1) //如果条件成立说明插入在r与p1之间
{
r->next=s;
s->next=p1;
}
else
{
s->next=p1; //否则插入在就绪队列的头
ready=s;
}


}
void insert2(PCB *q)
{
PCB *p1,*s,*r;
int b;
s=q; //指针s指向新要插入的进程
p1=ready; //指针p1指向原来的进程的对首
r=p1; //使用指针r指向p1前面的进程
b=1;
while((p1!=NULL)&&b)
{
if(p1->arrivetime<s->arrivetime)
{
r=p1;
p1=p1->next;
}
else
b=0;
}
if(r!=p1)
{
r->next=s;
s->next=p1;
}
else
{
s->next=p1;
ready=s;
}
}


void create1(char alg)
{
PCB *p;
int i,time;
char na[10];
ready=NULL; //就绪队列头指针
finish=NULL; //完成队列头指针
run=NULL; //运行队列头指针
//输入N个进程名和所需时间创建PCB
for(i=1;i<=N;i++)
{
printf("进程名:",i);
p=(PCB *)malloc(sizeof(PCB));
scanf("%s",na);
printf("所需时间:");
scanf("%d",&time);
strcpy(p->name,na);
p->cputime=0;
p->needtime=time;
p->state='W';
p->prio=rand()%10+1; //随机分配优先数[1,10]
if(ready!=NULL) //就绪队列不空则调用插入函数插入
insert1(p); //对新进程插入就绪队列
else
{
p->next=ready; //创建就绪队列的第一个PCB
ready=p;
}
}
system("cls");
printf(" 优先数算法结果输出\n");
printf("---------------------------------------------------------------------------\n");
prt(alg); //输出进程PCB信息
run=ready; //将就绪队列的第一个进程投入运行
ready=ready->next;
run->state='R';
}


void create2(char alg)
{
PCB *p;
int i;
ready=NULL;
run=NULL;
finish=NULL;
for(i=0;i<N;i++)
{
p=(PCB *)malloc(sizeof(PCB));
printf("进程名:");
scanf("%s",p->name);
printf("到达时间:");
scanf("%d",&p->arrivetime);
printf("需要时间:");
scanf("%d",&p->servicetime);
p->starttime=0;
p->finishtime=0;
p->state='W';
if(ready!=NULL)
insert2(p);//将新进程插入就绪队列
else
{
p->next=ready;//创建就绪队列的第一个
ready=p;
}
}
system("cls");
printf(" 先来先服务算法结果输出\n");
printf("---------------------------------------------------------------------------\n");
prt(alg);
}


void priority(char alg)
{
while(run!=NULL) //当运行队列不空时,有进程正在运行
{
run->cputime=run->cputime+1;
run->needtime=run->needtime-1;
run->prio=run->prio-1; //每运行一次优先数-1
if(run->prio<0) //如果优先数减到小于0,则转换成0
run->prio=0;
if(run->needtime==0) //如果所需时间为0,即完成,将其插入完成队列
{
run->next=finish;
finish=run;
run->state='F'; //置状态为完成态
run=NULL; //运行队列头指针为空
if(ready!=NULL) //如果就绪队列不空
firstin(); //将就绪对列的第一个进程投入运行
}
else //没有运行完同时优先数不是最大,则将其变为就绪态插入到就绪队列
if((ready!=NULL)&&(run->prio<ready->prio))
{
run->state='W'; //状态改为就绪
insert1(run); //将进程按优先数大小插入
firstin(); //将就绪队列的第一个进程投入运行
}
prt(alg); //输出进程PCB信息
}
}


void FCFS(char alg)
{ int time=0;//系统时间从0开始
do{
run=ready;//就绪序列的第一个进程放入run队列进行执行
run->state='R';//进程开始执行
ready=ready->next;//指向下一个
time=run->arrivetime>time? run->arrivetime:time;
run->starttime=time;//进程开始
prt(alg);//显示正在执行的进程
time=time+run->servicetime;//计算下个进程最小可开始时间
run->finishtime=time;//进程结束时间
run->state='F';//结束状态标识
prt(alg);//进程结束再显示
run->next=finish;
finish=run;//进程结束放入结束队列
run=NULL;
}while(ready!=NULL);
}
/*菜单显示函数*/
void Menu()
{
system("cls");
printf("请选择读取作业的方式:1.优先数算法 2.先来先服务算法\n");
printf("请输入编号:");
}


int main()
{
char algo; //接收算法编号
srand((unsigned)time(NULL));
system("cls");//清屏

Menu();//显示菜单
scanf("%d",&algo); //输入算法编号
switch(algo)
{
case 1:
system("cls");
printf("优先数算法:\n");
printf("请输入进程数目:");
scanf("%d",&N); //输入进程数
create1(algo); //创建队列
priority(algo);//优先数
break;
case 2:
system("cls");
printf("先来先服务算法:\n");
printf("请输入进程数目:");
scanf("%d",&N); //输入进程个数
create2(algo);//创建队列
FCFS(algo);//先来先服务
break;

default:
printf("输入有误\n");
break;
}


}

四、 实验总结

      这次试验使用了先来先服务算法和SJF算法去实现作业调度模拟程序,在学习这些算法的同时,不仅让我学到了很多算法思想,也很好开拓了我们的思维。

posted @ 2016-04-20 22:08  14邓金烨  阅读(173)  评论(0编辑  收藏  举报