实验二进程调度模拟程序
实验二进程调度模拟程序
一、 实验目的
用高级语言完成一个进程调度程序,以加深对进程的概念及进程调度算法的理解。
二、 实验内容和要求
设计一个有 N个进程并发执行的进程调度模拟程序。
进程调度算法:采用最高优先级优先的调度算法(即把处理机分配给优先级最高的进程)和先来先服务(若优先级相同)算法。
(1). 每个进程有一个进程控制块(PCB)表示。进程控制块包含如下信息:进程名、优先级、到达时间、需要运行时间、已用CPU时间、进程状态等等。
(2). 进程的优先级及需要的运行时间可以事先人为地指定,进程的运行时间以时间片为单位进行计算。
(3). 每个进程的状态可以是就绪 r(ready)、运行R(Running)、或完成F(Finished)三种状态之一。
(4). 就绪进程获得 CPU后都只能运行一个时间片。用已占用CPU时间加1来表示。
(5). 如果运行一个时间片后,进程的已占用 CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减1(即降低一级),然后把它插入就绪队列等待调度。
(6). 每进行一次调度程序都打印一次运行进程、就绪队列中各个进程的 PCB,以便进行检查。
(7). 重复以上过程,直到所要进程都完成为止。
三、 实验方法、步骤及结果测试
#include<stdio.h>
#include<malloc.h>
typedef struct process
{
char name[20];//进程名
float arriveTime;//进程到达时间
float startTime; //进程开始时间
float CPUTime;//进程已经占用cpu时间
float finishTime;//进程完成时间
float needTime;//进程到完成还要的时间
int prio; //进程优先数
char state;//设每个进程处于运行R、就绪W和完成F三种状态之一,并假设起始状态都是就绪状态R。
struct process *next;
}PCB;
PCB *start,*startHead,*temp,*newNode;//定义指针
int num;//进程数
void menu()
{
printf("\n\t-----------------欢迎进入进程调度模拟程序 1.0-----------------\n");
printf("\t ┏━━━━━━━━━━━━━━━━━━━━━━━━━┓\n");
printf("\t ┃可选择算法操作: ┃\n");
printf("\t ┣━━━━━━━━━━━━┳━━━━━━━━━━━━┫\n");
printf("\t ┃1.先来先服务算法 ┃2.优先数算法 ┃\n");
printf("\t ┣━━━━━━━━━━━━╋━━━━━━━━━━━━┫\n");
printf("\t ┃3. ┃4. ┃\n");
printf("\t ┣━━━━━━━━━━━━┻━━━━━━━━━━━━┫\n");
printf("\t ┃ 0.退出系统 ┃\n");
printf("\t ┗━━━━━━━━━━━━━━━━━━━━━━━━━┛\n");
}
void FCFS()
{
int i,Rflag=0;
float j,totalTime;
printf("\t -----------------进程调度(先来先服务)-----------------\n");
printf("\n请输入进程数:");
scanf("%d",&num);
start=(PCB*)malloc(sizeof(PCB));
startHead=(PCB*)malloc(sizeof(PCB));
// Waiting=(PCB*)malloc(sizeof(PCB));
// Running=(PCB*)malloc(sizeof(PCB));
start=NULL;
startHead=start;
temp=(PCB*)malloc(sizeof(PCB));
temp=startHead;
for(i=0;i<num;i++)
{
startHead=start;
temp=startHead;
newNode=(PCB*)malloc(sizeof(PCB));
printf("\n请输入进程名称:");
scanf("%s",&newNode->name);
printf("请输入进程到达时间:");
scanf("%f",&newNode->arriveTime);
printf("请输入进程需要时间:");
scanf("%f",&newNode->needTime);
newNode->state='W';
newNode->next=NULL;
if(i==0)
{
start=newNode;
startHead=start;
}
else if (i==1)
{
if(start->arriveTime <= newNode->arriveTime)
{
startHead->next = newNode;
}
else
{
newNode->next=startHead;
start=newNode;
}
}
else
{
for(startHead=start;startHead!=NULL;startHead=startHead->next)
{
temp=startHead;
if(start->arriveTime > newNode->arriveTime)
{
newNode->next=startHead;
start=newNode;
break;
}
else if(startHead->arriveTime <= newNode->arriveTime && startHead->next!=NULL && startHead->next->arriveTime > newNode->arriveTime)
{
newNode->next=startHead->next;
temp->next=newNode;
break;
}
else if(startHead->next==NULL)
{
temp->next=newNode;
break;
}
}
}
startHead=start;
}
system("cls");
/*if(startHead!=NULL)
{
printf("\t -----------------进程调度(先来先服务)-----------------\n");
printf("\n进程名称\t到达时间\t结束时间\t需要时间\t状态\n");
}*/
if(startHead!=NULL)
{
float sum = startHead->arriveTime;
do{
if(startHead->arriveTime<=sum)
{
sum=sum+startHead->needTime;
startHead->finishTime=sum;
startHead=startHead->next;
}
else
{
sum=sum+startHead->arriveTime;
startHead->finishTime=sum;
startHead=startHead->next;
}
}while(startHead!=NULL);
totalTime=sum;
startHead=start;
}
for(j=0;j<=totalTime;j++)
{
printf("\t -----------------进程调度(先来先服务)-----------------\n");
printf("\n进程名称\t到达时间\t结束时间\t需要时间\t状态\n");
for(i=0;startHead!=NULL;i++)
{
if(Rflag==0)
{
if(startHead->arriveTime<=j && startHead->state=='W')
{
startHead->state='R';
Rflag=1;
}
}
if(startHead->finishTime==j && startHead->state=='R')
{
startHead->state='F';
Rflag=0;
}
printf("%s\t\t",startHead->name);
printf("%0.2f\t\t",startHead->arriveTime);
printf("%0.2f\t\t",startHead->finishTime);
printf("%0.2f\t\t",startHead->needTime);
printf("%c\n",startHead->state);
if(startHead->state=='R')
{
startHead->needTime--;
}
startHead=startHead->next;
}
if(startHead==NULL) startHead=start;
printf("系统运行时间:");
printf("%0.2f\n",j);
system("pause");
system("cls");
}
printf("\n进程调度结束。\n");
}
void HRRN()
{
int i,Rflag=0;
float j;
printf("\t -----------------进程调度(最高优先数)-----------------\n");
printf("\n请输入进程数:");
scanf("%d",&num);
start=(PCB*)malloc(sizeof(PCB));
startHead=(PCB*)malloc(sizeof(PCB));
start=NULL;
startHead=start;
for(i=0;i<num;i++)
{
startHead=start;
temp=startHead;
newNode=(PCB*)malloc(sizeof(PCB));
printf("\n请输入进程名称:");
scanf("%s",&newNode->name);
printf("请输入进程优先数:");
scanf("%d",&newNode->prio);
printf("请输入进程需要时间:");
scanf("%f",&newNode->needTime);
newNode->state='W';
newNode->arriveTime=0;
newNode->CPUTime=0;
newNode->next=NULL;
if(i==0)
{
start=newNode;
startHead=start;
}
else if (i==1)
{
if(start->prio >= newNode->prio)
{
startHead->next = newNode;
}
else
{
newNode->next=startHead;
start=newNode;
}
}
else
{
for(startHead=start;startHead!=NULL;startHead=startHead->next)
{
temp=startHead;
if(start->prio < newNode->prio)
{
newNode->next=startHead;
start=newNode;
break;
}
else if(startHead->next==NULL)
{
temp->next=newNode;
break;
}
}
}
startHead=start;
}
system("cls");
/*if(startHead!=NULL)
{
printf("\t -----------------进程调度(最高优先数)-----------------\n");
printf("\n进程名称\t到达时间\t结束时间\t需要时间\t状态\n");
}*/
for(j=0;startHead!=NULL;j++)
{
printf("\t -----------------进程调度(最高优先数)-----------------\n");
printf("\n优先数\t\t进程名称\t需要时间\t运行时间\t状态\n");
for(i=0;startHead!=NULL;i++)
{
temp=startHead;
for(;startHead!=NULL;startHead=startHead->next)
{
if(temp->prio < startHead->next->prio)
{
temp->next=startHead->next->next;
startHead->next=temp;
}
}
printf("%d\t\t",startHead->prio);
printf("%s\t\t",startHead->name);
printf("%0.2f\t\t",startHead->needTime);
printf("%0.2f\t\t",startHead->CPUTime);
printf("%c\n",startHead->state);
if(startHead->state=='R')
{
startHead->CPUTime++;
}
startHead=startHead->next;
}
if(startHead==NULL) startHead=start;
printf("系统运行时间:");
printf("%0.2f\n",j);
system("pause");
system("cls");
}
printf("\n进程调度结束。\n");
}
int main()
{
int choose0;
char choose1;
do{
choose1='N';
menu();
printf("请选择对应序号:");
scanf(" %d",&choose0);
system("cls");
switch(choose0)
{
case 1:
FCFS();
fflush(stdin);
printf("\n是否返回主目录?(Y/N):");
choose1=getchar();
system("cls");
break;
case 2:
HRRN();
fflush(stdin);
printf("\n是否返回主目录?(Y/N):");
choose1=getchar();
system("cls");
break;
case 3:
printf("\n是否返回主目录?(Y/N):");
choose1=getchar();
system("cls");
break;
case 4:
printf("\n是否返回主目录?(Y/N):");
choose1=getchar();
system("cls");
break;
case 0:
break;
default:
choose1='Y';
printf("\n输入有误请重新输入。\n");
system("pause");
system("cls");
break;
}
}while(choose1=='Y'||choose1=='y');
printf("感谢您的使用。\n");
system("pause");
}
测试结果:
四、 实验总结
在算法过程,有多种不同情况需要出现,写算法时应该考虑全面防止出错