实验指南
运行环境:
Dev c++
算法思想:
本实验是模拟进程调度中的优先级算法,在先来先服务算法的基础上,只需对就绪队列到达时间进行一次排序。第一个到达的进程首先进入CPU,将其从就绪队列中出队后。若此后队首的进程的到达时间大于上一个进程的完成时间,则该进程进入CPU,其开始时间即到达时间;否则如果上一个进程完成后,已经有多个进程到达,则需从已到达的进程中寻找到优先级最高的进程,并将其取出,进入CPU执行。直到所有进程执行完毕。
核心数据结构:
typedef struct data{
int hour;
int minute;
}time;
typedef struct node{
int id;//进程编号
char name[20];//进程名
int good;//优先级
time arrive;//到达就绪队列的时间
int zx;//执行时间
time start;//开始执行时间
time finish;//执行完成时间
int zz;//周转时间=执行完成时间-到达就绪队列时间
float zzxs;//带权周转时间=周转时间/执行时间
struct node* next;
}Node;
typedef struct Queue{
Node* front = NULL;
Node* tail = NULL;
}Queue;
程序主体框架:
#include <iostream>
#include <stdio.h>
#include <malloc.h>
#include <string.h>
using namespace std;
typedef struct data{
int hour;
int minute;
}time;
typedef struct node{
int id;//进程编号
char name[20];//进程名
int good;//优先级
time arrive;//到达就绪队列的时间
int zx;//执行时间
time start;//开始执行时间
time finish;//执行完成时间
int zz;//周转时间=执行完成时间-到达就绪队列时间
float zzxs;//带权周转时间=周转时间/执行时间
struct node* next;
}Node;
typedef struct Queue{
Node* front = NULL;
Node* tail = NULL;
}Queue;
Queue* init(){
Queue* p = (Queue*)malloc(sizeof(Queue));
p->front = NULL;
p->tail = NULL;
return p;
}
//函数名:timecompare() 参数:tt 当前时间, p 进程到达时间
bool timecompare(time tt,time p){//tt<p(时间没到) false tt >= p true
//函数功能:比较进程到达时间和当前时间,若小于则返回false,否则返回true
}
//函数名:timecompare2() 参数:tt 当前时间, p 进程到达时间
bool timecompare2(time tt,time p){//tt<=p(时间没到) false tt > p true
//函数功能:比较进程到达时间和当前时间,若小于等于则返回false,否则返回true
}
//函数名:Levelcompare() 参数:p,q 进程
bool Levelcompare(Node* p,Node* q){
//函数功能:比较p,q的优先级,p的优先级高则返回true,低则返回false,否则比较到达时间,p先或同时到达则返回true,反之则false
}
//函数名:LevelSorted() 参数:que 进程队列指针
void LevelSorted(Queue* que){
//函数功能:对进程队列按优先级排序
}
//函数名:ComputeTime() 参数:tt 当前时间的指针,q 当前进程的指针
time ComputeTime(time* tt,Node* q){
//函数功能:更新当前时间和进程的各项时间
}
//函数名:priority() 参数:que进程队列指针,tt当前时间 n 进程数
Queue* priority(Queue *que,time tt,int n){
//函数功能:进行优先级进程调度,并同时更新当前时间。
}
//函数名:Print() 参数:que进程队列指针, n 进程数
void Print(Queue* que,int n){
//函数功能:打印输出进程优先进程调度结果
}
//函数名:ScanIn() 参数:wait进程队列指针, n 进程数
time ScanIn(Queue* wait,int n){
//函数功能:输入进程信息,返回最早的进程到达时间
}
int main(){
Queue* wait;
wait = init();
int flag,n;
time earlytime;
while(1){
printf("请输入操作:(1:开始进程;0:结束进程):");
scanf("%d",&flag);
if(flag == 0){
printf("\n操作结束!\n");
break;
}
else{
printf("请输入进程数量:");
scanf("%d",&n);
earlytime = ScanIn(wait,n);
LevelSorted(wait);
wait = priority(wait,earlytime,n);
Print(wait,n);
wait = init();
}
}
return 0;
}
测试数据
/*
1001 p1 1 9:40 20
1004 p4 4 10:10 10
1005 p5 3 10:05 30
1002 p2 3 9:55 15
1003 p3 2 9:45 25*/
/*
5001 p1 1 14:40 20
5002 p4 2 10:10 10
5003 p5 3 10:05 30
5004 p2 4 9:55 15
5005 p3 5 9:45 25
5006 p6 6 10:40 20
5007 p8 7 11:10 10
5008 p9 8 12:05 30
5009 p10 9 13:55 15
5010 p7 10 7:15 15*/
关键代码
#include <iostream>
#include <stdio.h>
#include <malloc.h>
#include <string.h>
using namespace std;
typedef struct data{
int hour;
int minute;
}time;
typedef struct node{
int id;//进程编号
char name[20];//进程名
int good;//优先级
time arrive;//到达就绪队列的时间
int zx;//执行时间
time start;//开始执行时间
time finish;//执行完成时间
int zz;//周转时间=执行完成时间-到达就绪队列时间
float zzxs;//带权周转时间=周转时间/执行时间
struct node* next;
}Node;
typedef struct Queue{
Node* front = NULL;
Node* tail = NULL;
}Queue;
void Print(Queue* que,int n);
Queue* init(){
Queue* p = (Queue*)malloc(sizeof(Queue));
p->front = NULL;
p->tail = NULL;
return p;
}
//函数名:timecompare() 参数:tt 当前时间, p 进程到达时间
bool timecompare(time tt,time p){//tt<p(时间没到) false tt >= p true
//函数功能:比较进程到达时间和当前时间,若小于则返回false,否则返回true
if((tt.hour<p.hour)||((tt.hour==p.hour)&&(tt.minute<p.minute)))
return false;
else
return true;
}
//函数名:timecompare2() 参数:tt 当前时间, p 进程到达时间
bool timecompare2(time tt,time p){//tt<=p(时间没到) false tt > p true
//函数功能:比较进程到达时间和当前时间,若小于等于则返回false,否则返回true
if((tt.hour<p.hour)||((tt.hour==p.hour)&&(tt.minute<p.minute||tt.minute==p.minute)))
return false;
else
return true;
}
//函数名:Levelcompare() 参数:p,q 进程
bool Levelcompare(Node* p,Node* q){
//函数功能:比较p,q的优先级,p的优先级高则返回true,低则返回false,否则比较到达时间,p先或同时到达则返回true,反之则false
if(p->good>q->good)
return true;
else if(p->good<q->good)
return false;
else
{
if((p->arrive.hour<q->arrive.hour)||(p->arrive.hour==q->arrive.hour&&p->arrive.minute<=q->arrive.minute))
return true;
else
return false;
}
}
//函数名:LevelSorted() 参数:que 进程队列指针
void LevelSorted(Queue* que){
//函数功能:对进程队列按优先级排序
Node *bl,*head=NULL,*pre=NULL,*q=NULL,*p,*c;
bl=que->front;
while(bl!=NULL)
{
Node *p=(Node *)malloc(sizeof(Node));
*p=*bl;//重点:指针的应用
p->next=NULL;
if(head==NULL)
{
head=p;
q=p;
}
else
{
q=head;
pre=NULL;
while(q!=NULL)
{
if(Levelcompare(p,head))
{
p->next=head;
head=p;
q=head;
break;
}
else if(!Levelcompare(p,q)&&q->next==NULL)
{
q->next=p;
break;
}
else if(Levelcompare(p,q))
{
p->next=q;
pre->next=p;
break;
}
pre=q;
q=q->next;
}
}
bl=bl->next;
}
que->front=head;
que->tail=pre;
}
//函数名:ComputeTime() 参数:tt 当前时间的指针,q 当前进程的指针
time ComputeTime(time* tt,Node* q){
//函数功能:更新当前时间和进程的各项时间
q->start.hour=tt->hour;
q->start.minute=tt->minute;
q->finish.minute=(q->start.minute+q->zx)%60;
q->finish.hour=q->start.hour+(q->start.minute+q->zx)/60;
q->zz=q->finish.hour*60+q->finish.minute-q->arrive.hour*60-q->arrive.minute;
q->zzxs=q->zz*1.0/q->zx;
tt->hour=q->finish.hour;
tt->minute=q->finish.minute;
}
//函数名:priority() 参数:que进程队列指针,tt当前时间 n 进程数
Queue* priority(Queue *que,time tt,int n){
//函数功能:进行优先级进程调度,并同时更新当前时间。
int count=n;
Node *pre=NULL,*p=NULL,*head=NULL,*q=NULL,*Head;
Head=que->front;
p=Head;
while(1)
{
if((p->arrive.hour==tt.hour)&&(p->arrive.minute==tt.minute))
{
break;
}pre=p;
p=p->next;
}
Node *N=(Node *)malloc(sizeof(Node));
*N=*p;
N->next=NULL;
head=N;
q=head;
if(p==Head)
{
Head=Head->next;
free(p);
count--;
}
else
{
pre->next=p->next;
free(p);
count--;
}
ComputeTime(&tt,N);
while(count)
{
p=Head;
pre=NULL;
while(p!=NULL)
{
if(timecompare2(tt,p->arrive)==true)//提前到达
{
Node *N=(Node *)malloc(sizeof(Node));
*N=*p;
N->next=NULL;
q->next=N;
q=q->next;
if(p==Head)
{
Head=Head->next;
free(p);
count--;
}
else
{
pre->next=p->next;
free(p);
count--;
}
ComputeTime(&tt,N);
break;
}
pre=p;
p=p->next;
}
if(p==NULL)//按到达时间先后
{
Node *l,*r;
l=Head;
r=Head;
while(r!=NULL)
{
if(timecompare2(l->arrive,r->arrive))
{
l=r;
}
r=r->next;
}//找到最小到达时间
tt.hour=l->arrive.hour;tt.minute=l->arrive.minute;
Node *N=(Node *)malloc(sizeof(Node));
*N=*l;
N->next=NULL;
q->next=N;
q=q->next;pre=Head;
if(l==Head)
{
Head=Head->next;
free(l);
count--;
}
else
{
while(pre->next!=l)
{
pre=pre->next;
}
pre->next=l->next;
free(l);
count--;
}
ComputeTime(&tt,N);
}
}
que->front=head;
return que;
}
//函数名:Print() 参数:que进程队列指针, n 进程数
void Print(Queue* que,int n){
//函数功能:打印输出进程优先进程调度结果
float pz=0,px=0;
Node *p;
p=que->front;
printf("模拟进程优先进程调度过程输出结果\n id号 名字\t优先级\t到达时间 执行时间(分钟)\t开始时间\t完成时间 周转时间(分钟) 带权周转系数\n");
while(p!=NULL)
{
printf("%6d %6s %6d %6d:%02d %10d %17d:%02d %12d:%02d %10d(分钟) %12.2f\n",p->id,p->name,p->good,p->arrive.hour,p->arrive.minute,p->zx,p->start.hour,p->start.minute,p->finish.hour,p->finish.minute,p->zz,p->zzxs);
pz=pz+p->zz;
px=px+p->zzxs;
p=p->next;
}
printf("系统平均周转时间为:\t\t\t\t\t\t\t\t\t%.2f\n",pz/n);
printf("系统平均带权周转系数为: \t\t\t\t\t\t\t\t\t\t%.2f\n",px/n);
}
//函数名:ScanIn() 参数:wait进程队列指针, n 进程数
time ScanIn(Queue* wait,int n){
//函数功能:输入进程信息,返回最早的进程到达时间
int count;
count=n;
time N;
Node *q;
q=wait->tail;
printf("请输入进程的参数:\nid号 名字 优先级 到达时间 执行时间(分钟):\n");
while(count--)
{
Node *p=(Node *)malloc(sizeof(Node));
p->next=NULL;
scanf("%d %s %d %d:%d %d",&p->id,&p->name,&p->good,&p->arrive.hour,&p->arrive.minute,&p->zx);
if(wait->front==NULL&&wait->tail==NULL)
{
wait->front=p;
q=p;
N.hour=p->arrive.hour;
N.minute=p->arrive.minute;
}
else
{
q->next=p;
q=p;
wait->tail=p;
if((p->arrive.hour<N.hour)||((p->arrive.hour==N.hour)&&(p->arrive.minute<N.minute)))
{
N.hour=p->arrive.hour;
N.minute=p->arrive.minute;
}
}
}
return N;
}
int main(){
Queue* wait;
wait = init();
int flag,n;
time earlytime;
while(1){
printf("请输入操作:(1:开始进程;0:结束进程):");
scanf("%d",&flag);
if(flag == 0){
printf("\n操作结束!\n");
break;
}
else{
printf("请输入进程数量:");
scanf("%d",&n);
earlytime = ScanIn(wait,n);//函数功能:输入进程信息,返回最早的进程到达时间
LevelSorted(wait);//函数功能:对进程队列按优先级排序
wait = priority(wait,earlytime,n);//函数功能:进行优先级进程调度,并同时更新当前时间。
Print(wait,n);//函数功能:打印输出进程优先进程调度结果
wait = init();
}
}
return 0;
}
运行结果
实验总结
1、在开始实验之前必须有正确的设计思路
2、理解了优先级的进程调度,当时间和优先级冲突时,首先考虑优先级
3、如果有两个Node *p,q;则p=q和*p=*q的含义是不同的,前者表示两者指向同一个结点,后者表示赋值
4、单链表的创建和应用还不是很熟练,还得多加练习。