短进程优先进程调度算法(c语言实现)

本实验是模拟进程调度中的短进程优先调度算法,每次CPU都是从进入就绪队列中选取执行时间最短的一个进程装入CPU运行,等结束时再同理选取下一个。相应的数据结构如下:

typedef struct  data

{

    int hour;

    int min;

}time;

typedef struct node

{

    int id;//编号

    char name[20];//进程名

    time arrive;//到达就绪队列时间

    int zx;//执行时间

    time start;//开始时间

    time finish;//完成时间

    int zz;//周转时间=完成时间-到达就绪队列时间

    float zzxs;//带权周转时间系数=周转时间/执行时间

    struct node* next;

}linklist;

算法实现:每次输入一个进程的ID号、名字、到达就绪队列时间和执行时间,然后依次计算出该进程的开始运行时间和完成、周转、带权周转时间等;然后边输出每个进程的信息同时计算出系统的平均周转时间及平均带权周转时间

代码实现

/*
短进程优先 (SPF)调度算法则是从就绪队列中选出一个估计运行时间最短的进程,
将处理机分配给它,使它立即执行并一直执行到完成
*/

#include
#include
typedef struct data{
    int hour;
    int min;
}time;
typedef struct node{
    int id;//编号
    char name[20];//名字
    time arrive;//到达时间
    int zx;//执行时间;
    time start;//开始时间
    time finish;//完成时间
    int zz;//周转时间=执行完成时间-到达就绪队列时间
    double zzxs;//带权周转时间=周转时间/执行时间
    struct node* next;
}linknode;

typedef linknode* linklist;

typedef struct{
    linklist front;
    linklist rear;
}queue;   //队列
//函数名:init   参数:无
queue* init(){
//函数功能:初始化队列,返回队列指针
    queue* q = (queue*)malloc(sizeof(queue));
    q->front = NULL;
    q->rear = NULL;
    return q;
}
int timeCompare(time t1,time t2) {
    if(t1.hour<t2.hour) {
        return 1;
    }
    if(t1.hour>t2.hour) {
        return 0;
    }
    if(t1.min<=t2.min) {
        return 1;
    }else{
        return 0;
    }
}
int zxCompare(int t1,int t2) {
	if(t1<=t2) {
		return 1;
	}else{
		return 0;
	}
} 
//函数名:insert  参数:Queue *cc, node *x
void insert(queue* cc,linklist s){
    //函数功能:尾插入队
    linklist p,pre;
    pre=NULL;
    p=cc->front;
    s->next=NULL;
    if(p==NULL) {
        cc->front=cc->rear=s;
        return;
    }
    // p=cc->rear;
    // p->next=s;
    while(p!=NULL&&timeCompare(p->arrive,s->arrive)) {
        pre=p;
        p=p->next;
    }
    if(p==NULL) {
        cc->rear->next=s;
        cc->rear=s;
    }else{
        if(p==cc->front) {
        	s->next=p;
        	cc->front=s;
        	return;
		} 
		s->next=p;
        pre->next=s;
    }

}
//函数名:dele  参数:Queue *cc
void dele(queue* cc){ 
//功能:队首结点出队
    linklist p;
    p=cc->front;
    if(p==NULL) {
        return;
    }
    cc->front=cc->front->next;
}
//函数名:input   参数:Queue *cc
void input(queue* cc){
//功能:实现作业队列的输入
    printf("请输入进程数:\n");
    int num;
    scanf("%d",&num);
    printf("id号\t名字\t到达\t执行\n");

    for(int i=0;i<num;i++) {
        linklist p = (linklist)malloc(sizeof(linknode));
        scanf("%d\t%s\t%d:%d\t%d",&p->id,p->name,&p->arrive.hour,&p->arrive.min,&p->zx);
        insert(cc,p);
    }
}


void output(queue* cc) {
    linklist p;
    p=cc->front;
    printf("\n模拟短进程优先调度过程输出结果:\n");
    printf("id号\t名字\t到达\t执行\t开始\t完成\t周转\t带权周转系数\n");
    int num=0;
    double zzxs=0,zz=0;
    while(p!=NULL) {
        num++;
        zz+=p->zz;
        zzxs+=p->zzxs;
        printf("%d\t%s\t%02d:%02d\t%d\t%02d:%02d\t%02d:%02d\t%d\t%.2f\n",p->id,p->name,p->arrive.hour,p->arrive.min,p->zx,p->start.hour,p->start.min,p->finish.hour,p->finish.min,p->zz,p->zzxs);
        p=p->next;
    }
    printf("系统平均周转时间为:\t\t\t\t%.2f\n",zz/num);
    printf("系统平均周转系数为:\t\t\t\t\t%.2f\n",zzxs/num);
}

time computer(time arrive,int zx) {
    int total=arrive.hour*60+arrive.min+zx;
    time t;
    t.hour=total/60;
    t.min=total%60;
    return t;
}

void computerArgs(queue* cc) {  //计算参数
    linklist p=cc->front,pre=NULL;

    while(p!=NULL) {
        if(p==cc->front) {
            p->start=p->arrive;
        }else{ //不是第一个
            if(timeCompare(pre->finish,p->arrive)) {
                p->start=p->arrive;
            }else{
                p->start=pre->finish;
            }
        }
        p->zz=p->finish.hour*60+p->finish.min-p->arrive.hour*60-p->arrive.min;
        p->zzxs=(double)p->zz/(double)p->zx;
        pre=p;
        p=p->next;
    }
}

//函数名:solve_SJF参数:Queue *cc
void solve_SJF(queue* cc){	
//函数功能:解决短进程优先调度算法 
    linklist p=cc->front;
    p->finish=computer(p->arrive,p->zx);
    while(p!=NULL) {
        linklist tmp=p->next;
        linklist pos=NULL;
        while(tmp!=NULL&&timeCompare(tmp->arrive,p->finish)) { 
            pos=tmp; // 找到执行进程时,到达的最后一个队列
            tmp=tmp->next;
        }
        linklist qre,q,tmr;
        qre=p;
        q=p->next;
        tmr=p;
        tmp=p->next;

        while(pos!=NULL&&q!=pos) {
                if(!zxCompare(q->zx,q->next->zx)) {
                	tmr=q;
                    tmp=q->next;
                	if(q->next==pos) {
                		break; 
					} 
                    
                }else{
                    qre=q;
                    q=q->next;
                }
        }
        if(tmp!=NULL) {
        	tmr->next=tmp->next;
        	tmp->next=p->next;
        	p->next=tmp;
		}
        
        tmp=p;
        p=p->next;
        if(p==NULL) {
        	continue;
		}
        if(timeCompare(p->arrive,tmp->finish)) {
            p->finish=computer(tmp->finish,p->zx);
        }else {
            p->finish=computer(p->arrive,p->zx);
        }
    }
    computerArgs(cc);  //计算结果
    output(cc);        //输出
}



int main()
{
    while(1)
    {
        int op;
        printf("请输入操作,1:开始进程调度;0:结束进程:\n");
        scanf("%d",&op);
        if(op==0) break;
        queue *cc;
        cc = init();
        input(cc);
        solve_SJF(cc);
    }


    return 0;
}
/*
测试用例:
1001    p1  9:40    20
1004    p4  10:10   10
1005    p5  10:05   30
1002    p2  9:55    15
1003    p3  9:45    25


5001    p1  19:40   20
5002    p4  10:10   10
5003    p5  10:05   30
5004    p2  9:55    15
5005    p3  9:45    25
5006    p6  11:40   20
5007    p8  12:10   10
5008    p9  13:05   30
5009    p1  19:55   15
5010    p7  7:15    15
*/

预期结果

短进程优先进程调度算法(c语言实现)_第1张图片

你可能感兴趣的:(操作系统,算法,c语言,数据结构)