先来先服务短作业优先高响应比调度作业C语言实现

#include <stdio.h>
#include <stdlib.h>
#include<dos.h>
#include<time.h>
#include<conio.h>
#include<string.h>
#define INF 1000000.0

typedef char string[10];
struct task
{
    int    ID;                //进程号
    string    name;            //进程名
    int        arrivetime;        //到达时间
    int        servicetime;    //服务时间
    int     waittime;        //等待时间
    int        starttime;        //开始运行时间
    int        finishtime;        //结束运行时间        
    float    turnaroundtime;    //周转时间
    float    weightedturnaroundtime;    //带权周转时间
    int        priority;        //优先权
    int     finish;            //是否已经完成
}PCB[10];
 
struct PCB {
    char id[10];    // 进程ID
    double reachTime;  // 进程到达的时间
    double needTime;   // 进程完成需要的时间
    double startTime;  // 进程开始的时刻
    double finishTime; // 进程完成的时刻
    double cTime;      // 进程周转时间
    double wcTime;     // 进程带权周转时间
    char state;       // 进程的状态( 设每个进程处于就绪R(ready),完成F(finish)两种状态之一 )
};
int num;
void input()
{
    int i;

    printf("\n请输入作业数量:");
    scanf("%d",&num);
    for(i=0;i<num;i++)
    {
        printf("\n请输入进程%d:\n",i);
        printf("进程名 到达时间 服务时间\n");
        scanf("%s%9d%9d",PCB[i].name,&PCB[i].arrivetime,&PCB[i].servicetime);
        PCB[i].priority=0;
        PCB[i].finish=0;
    }
}
int HRN(int pre)
{
    int current=1,i,j;    //优先权=(等待时间+要求服务时间)/要求服务时间
    for(i=0;i<num;i++)
    {
        PCB[i].waittime=PCB[i].finishtime-PCB[i].arrivetime;    //等待时间=上一个进程的完成时间-到达时间
        PCB[i].priority=(PCB[i].waittime+PCB[i].servicetime)/PCB[i].servicetime;
    }
    for(i=0;i<num;i++)
    {
        if(!PCB[i].finish)
        {
            current=i;    //找到第一个还没完成的作业
            break;
        }
    }
    for(j=i;j<num;j++)    //和后面的作业比较
    {
        if(!PCB[i].finish)    //还没完成(运行)
        {
            if(PCB[current].arrivetime<=PCB[pre].finishtime)    //如果进程在上一个进程完成之前到达
            {
                if(PCB[j].arrivetime<=PCB[pre].finishtime && PCB[j].priority>PCB[current].priority)
                current=j;    //找出到达时间在上一个进程完成之前,优先权高的进程
            }
            else    //如果进程是在上一个进程完成之后到达
            {
                if(PCB[j].arrivetime<PCB[current].arrivetime)
                    current=j;    //找出比较早到达的一个
                if(PCB[j].arrivetime==PCB[current].arrivetime)    //如果同时到达
                if(PCB[j].priority>PCB[current].priority)
                    current=j;    //找出服务时间比较短的一个
            }
        }
    }
    return current;    //返回当前进程
}
void running(int i,int times,int pre,int statime,int endtime)
{
    if(times==0)
    {
        PCB[i].starttime=PCB[i].arrivetime;
        PCB[i].finishtime=PCB[i].starttime+PCB[i].servicetime;
        PCB[i].turnaroundtime=PCB[i].servicetime;
        PCB[i].weightedturnaroundtime=1.0;
        statime=PCB[i].starttime;
    }
    else
    {
        if(PCB[i].arrivetime>PCB[pre].finishtime)
            PCB[i].starttime=PCB[i].arrivetime;
        else
            PCB[i].starttime=PCB[pre].finishtime;
        PCB[i].finishtime=PCB[i].starttime+PCB[i].servicetime;
        PCB[i].turnaroundtime=PCB[i].finishtime-PCB[i].arrivetime;
        PCB[i].weightedturnaroundtime=PCB[i].turnaroundtime/PCB[i].servicetime;
    }
    if(times==num-1)
        endtime=PCB[i].finishtime;
    PCB[i].finish=1;
}
void print(int i,int times)
{
    if(times==0)
    {
        printf("ID    进程名 到达时间 服务时间 开始时间 完成时间 周转时间 带权周转时间\n");
    }
        printf("%d%9s%9d%9d%9d%9d%10.1f%10.2f\n",PCB[i].ID,PCB[i].name,PCB[i].arrivetime,PCB[i].servicetime,
                PCB[i].starttime,PCB[i].finishtime,PCB[i].turnaroundtime,PCB[i].weightedturnaroundtime);
}
void check()
{
    int i;
    int statime,endtime,sumturtime=0.00,sumwtutime=0.00;
    int current=0,times=0,pre=0;
    float aveturtime,avewtutime;
    PCB[pre].finishtime=0;
    for(i=0;i<num;i++)
    {
        PCB[i].finish=0;
    }
    statime,endtime,sumturtime=0.00,sumwtutime=0.00,aveturtime,avewtutime;
    current=0;times=0;pre=0;
    PCB[pre].finishtime=0;
    printf("\n");
    for(i=0;i<num;i++)
    {
        PCB[i].finish=0;
    }
    statime,endtime,sumturtime=0.00,aveturtime,avewtutime;
    current=0;times=0;pre=0;
    PCB[pre].finishtime=0;
    printf("\n");
    for(times=0;times<num;times++)
    {
        current=HRN(pre);
        running(current,times,pre,statime,endtime);
        print(current,times);
        pre=current;
    }
    float sum=0;
    for(i=0;i<num;i++)
    {
        sumturtime+=PCB[i].turnaroundtime;
        sum=sum+PCB[i].weightedturnaroundtime;
        
    }

    aveturtime=sumturtime/num;
    avewtutime=sum/num;
    
    printf("(平均带权周转时间)            %.3lf\n",avewtutime);
    printf("\n");
}
void hrrn()
{
input();
check();
}
 
/* 两种情况:
   1.在lastTime时刻,选择已经到达且拥有最短运行时间的进程
   2.在lastTime时刻,没有进程到达,此时选择拥有最早到达时间的进程
*/
int findNext( struct PCB arr[], int length, double lastTime ) {
    // p是已经到达且拥有最短运行时间的进程的下标
    // q是没有到达的进程中拥有最早到达时间的进程的下标
    int i, p, q;
    double minNeedTime, minReachTime,minTime;
    minTime= 1000000;
    p = q = -1; minNeedTime = minReachTime = INF;
    for( i = 0; i < length; i++ ) {
        if( arr[i].state=='R' ) { // 进程处就绪状态
            // 第一情况
            if( arr[i].reachTime<=lastTime && arr[i].needTime<minNeedTime )
                { p = i; minNeedTime = arr[i].needTime; }
            // 第二种情况
            if( arr[i].reachTime>lastTime && arr[i].reachTime<=minReachTime  ){
                if(arr[i].needTime<minTime)
                { q = i; minReachTime = arr[i].reachTime; minTime = arr[i].needTime; }
        }}
    }
    // p为-1时,代表在lastTime时刻还没进程到达,此时选择下一个最早到达的进程q
        printf("%d------------",q);
    if( p != -1 ) return p;

    return q;
}
 
int sjf(){
    int num, i;
    double lastTime;  // 为上一个进程的完成时间,用来确定当前进程的开始时间
    struct PCB *arr;
 
    printf( "请输入进程数:" );
    scanf( "%d", &num );
    arr = (struct PCB*)malloc(num*sizeof(struct PCB));
 
    lastTime = INF;  // 最开始lastTime的为第一个作业的reachTime(到达时间)
    printf( "请依次输入进程ID,进程到达时间,进程运行时间:\n" );
    for( i = 0; i < num; i++ ) {
        scanf( "%s%lf%lf", arr[i].id, &arr[i].reachTime, &arr[i].needTime );
        arr[i].state = 'R';
        if( lastTime>arr[i].reachTime ) lastTime = arr[i].reachTime;
    }
 
    // sum1为所有进程周转时间之和,sum2为所有进程带权周转时间之和
    double sum1=0.0, sum2=0.0;
    for( i = 0; i < num; i++ ) {
        int p = findNext( arr, num, lastTime ); // 找到下一个将要执行的进程
        // 两种情况:将要执行的进程可能已经到达,或者还没到达
        if( arr[p].reachTime<=lastTime ) arr[p].startTime = lastTime;
        else arr[p].startTime = arr[p].reachTime;
        // 确定进程的完成时间,周转时间,带权周转时间
        arr[p].finishTime = arr[p].startTime + arr[p].needTime;
        arr[p].cTime = arr[p].finishTime - arr[p].reachTime;
        arr[p].wcTime = arr[p].cTime/arr[p].needTime;
        arr[p].state = 'F';
 
        sum1 += arr[p].cTime;
        sum2 += arr[p].wcTime;
 
        lastTime = arr[p].finishTime; // 更新lastTime
    }
 
    printf( "\n进程  到达时间  运行时间  开始时间  完成时间  周转时间  带权周转时间\n" );
    for( i = 0; i < num; i++ ) {
        printf( "%4s  %8.2lf  %8.2lf  ", arr[i].id, arr[i].reachTime, arr[i].needTime );
        printf( "%8.2lf  %8.2lf  ", arr[i].startTime, arr[i].finishTime );
        printf( "%8.2lf  %12.2lf\n", arr[i].cTime, arr[i].wcTime );
    }
    printf( "平均周转时间: %.3lf\n", sum1/num );
    printf( "平均带权周转时间: %.3lf\n", sum2/num );
    return 0;
}
int cmp( const void *a, const void *b ) {
    if( ((struct PCB*)a)->reachTime < ((struct PCB*)b)->reachTime ) return -1;
    return 1;
}
 
int fcfs(){
    int num, i;
    double lastTime;  // 为上一个进程的完成时间,用来确定当前进程的开始时间
    struct PCB *arr;
 
    printf( "请输入进程数:" );
    scanf( "%d", &num );
    arr = (struct PCB*)malloc(num*sizeof(struct PCB));
 
    lastTime = INF;  // 最开始lastTime的为第一个作业的reachTime(到达时间)
    printf( "请依次输入进程ID,进程到达时间,进程运行时间:\n" );
    for( i = 0; i < num; i++ ) {
        scanf( "%s%lf%lf", arr[i].id, &arr[i].reachTime, &arr[i].needTime );
        arr[i].state = 'R';
        if( lastTime>arr[i].reachTime ) lastTime = arr[i].reachTime;
    }
 
    qsort( arr, num, sizeof(struct PCB), cmp ); // 将进程按reachTime(到达时间)进行排序
    // sum1为所有进程周转时间之和,sum2为所有进程带权周转时间之和
    double sum1=0.0, sum2=0.0;
    for( i = 0; i < num; i++ ) {
        int p = i; // 找到下一个将要执行的进程
        // 两种情况:将要执行的进程可能已经到达,或者还没到达
        if( arr[p].reachTime<=lastTime ) arr[p].startTime = lastTime;
        else arr[p].startTime = arr[p].reachTime;
        // 确定进程的完成时间,周转时间,带权周转时间
        arr[p].finishTime = arr[p].startTime + arr[p].needTime;
        arr[p].cTime = arr[p].finishTime - arr[p].reachTime;
        arr[p].wcTime = arr[p].cTime/arr[p].needTime;
        arr[p].state = 'F';
 
        sum1 += arr[p].cTime;
        sum2 += arr[p].wcTime;
 
        lastTime = arr[p].finishTime; // 更新lastTime
    }
 
    printf( "\n进程  到达时间  运行时间  开始时间  完成时间  周转时间  带权周转时间\n" );
    for( i = 0; i < num; i++ ) {
        printf( "%4s  %8.2lf  %8.2lf  ", arr[i].id, arr[i].reachTime, arr[i].needTime );
        printf( "%8.2lf  %8.2lf  ", arr[i].startTime, arr[i].finishTime );
        printf( "%8.2lf  %12.2lf\n", arr[i].cTime, arr[i].wcTime );
    }
    printf( "平均周转时间: %.3lf\n", sum1/num );
    printf( "平均带权周转时间: %.3lf\n", sum2/num );
    return 0;
}

void main(){
        for(int i=0;i<3;i++){
    printf("\n-------------算法选择--------------\n");
    printf("\n1.短作业优先算法\n");
        printf("\n2.先来先服务算法\n");
            printf("\n3.高响应比优先调度算法算法\n");
                
            int a=0;
            
                    printf("\n请选择序号:\n");
                    a=0;
            scanf("\n%d",&a);
            switch(a){ 
            case 1:{    printf("\n-------------短作业优先算法--------------\n");
                sjf();break;}
            case 2:{    printf("\n-------------先来先服务算法--------------\n");
                fcfs();
            
                break;}
            case 3:{
                    printf("\n-------------高响应比优先调度算法算法--------------\n");
                    hrrn();break;}
            }}

}

  • 5
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值