模拟CPU调度算法

定义一个结构体来模拟PCB,通过定义各种时间再对时间数字进行加减来模拟进程的执行。

FCFS,RR,SJF,Priority

#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include<pthread.h>
#include<time.h>
#include<stdbool.h>

#define ThreadNum 5  //预先定义20个任务进行调度
#define Ready 0
#define Waitting 1
#define Finish 2

typedef struct VirtualPCB{
    int tid;
    int priority;
    int waittime;
    int runtime;
    int arrivetime;
    int visited;
    int tempruntime;  //还没运行的时间
    int state;
    int begintime;
    int endtime;
    struct VirtualPCB* next;
}VirtualPCB;

struct VirtualPCB* head;//头指针
struct VirtualPCB* end;//尾指针


pthread_mutex_t Device_mutex;


void init(){
    int n;
    srand(time(NULL));
    head=malloc(sizeof(struct VirtualPCB));
    head->next=NULL;
    end=head;
    for(n=0;n<ThreadNum;n++){
        //将节点插入队尾
        struct VirtualPCB* temp=malloc(sizeof(struct VirtualPCB));
        temp->tid=n+1;
        temp->priority=1+rand()%5;  //一共有5个优先级,1~5
        temp->runtime=2+rand()%10; //运行时间随机指定?
        temp->arrivetime=1+rand()%4;
        temp->waittime=0;
        temp->tempruntime=temp->runtime;
        temp->state=Ready;
        end->next=temp;
        end=temp;
        printf("task%d create finished.  priority:%d,waittime:%d,runtime:%d,arrivetime:%d\n",temp->tid,temp->priority,temp->waittime,temp->runtime,temp->arrivetime);      
    }
    //对初始化结果进行验证
    /*struct VirtualPCB* cur=head->next;
    while(cur!=NULL){
        printf("%d\n",cur->tid);
        cur=cur->next;
    }*/
    printf("--------------------------------------inin finish----------------------------------\n\n");
    
}

//FCFS
bool empty(){
    return ThreadNum==0;
}

void swap(int* a,int* b){
    int temp=*a;
    *a=*b;
    *b=temp;
}

void sortByAT(){//sort by arrive time
    struct VirtualPCB temp;
    if(empty()||ThreadNum==1){
        return;
    }
    struct VirtualPCB* prev;
    struct VirtualPCB* cur;
    for(int i=0;i<ThreadNum-1;i++){  //冒泡排序
        prev=head->next;
        cur=prev->next;  
        for(int j=0;j<ThreadNum-i-1;j++){
            if((prev->arrivetime)>(cur->arrivetime)){
                //printf("into swap\n");
                swap(&(prev->tid),&(cur->tid));
                swap(&(prev->priority),&(cur->priority));
                swap(&(prev->waittime),&(cur->waittime));
                swap(&(prev->runtime),&(cur->runtime));
                swap(&(prev->arrivetime),&(cur->arrivetime));
                swap(&(prev->visited),&(cur->visited));
                swap(&(prev->tempruntime),&(cur->tempruntime));
                swap(&(prev->state),&(cur->state));
            }
            prev=prev->next;
            cur=cur->next;
        }
    }
}

void FCFS(){
    printf("FCFS-------------------------------------\n");
    int totalWaittime=0;
    int currenttime=head->next->arrivetime;
    if(empty()){
        printf("no task\n");
        exit(-1);
    }
    sortByAT();
    /*对排序结果进行检测
    struct VirtualPCB* cur=head->next;
    while(cur!=NULL){
        printf("%d  %d\n",cur->tid,cur->arrivetime);
        cur=cur->next;
    }*/
    struct VirtualPCB* cur=head->next;
    while(cur!=NULL){
        cur->begintime=currenttime;
        cur->waittime=cur->begintime-cur->arrivetime;
        cur->state=Finish;
        totalWaittime=totalWaittime+cur->waittime;
        currenttime=currenttime+cur->runtime;
        if(cur->state==Finish){
            printf("task%d finished.  priority:%d,waittime:%d,runtime:%d,arrivetime:%d\n",cur->tid,cur->priority,cur->waittime,cur->runtime,cur->arrivetime);
        }
        cur=cur->next;
    }
    printf("FCFS schedule finished.Average waittime is %d.\n",totalWaittime/ThreadNum);
}



//RR
void RR(){
    printf("RR-----------------------------------------\n");
    int FinNum=0;  //结束了的数量
    int slice=2;//时间片大小为2
    int sliceAvailable=slice;   //可用的时间片的大小(由于时间片如果未使用完还可被下一时间片使用)
    int totalWaittime=0;
    sortByAT();
    int currenttime=(head->next)->arrivetime;
    struct VirtualPCB* cur=head->next;
    struct VirtualPCB* pre=head;
    while(FinNum!=ThreadNum){
        if(cur->state!=Finish){
            if(cur->state==Ready){
                cur->begintime=currenttime;
                cur->state=Waitting;
            }
            if(cur->tempruntime<sliceAvailable){
printf("t<a %d %d\n",cur->tid,sliceAvailable);
                currenttime=currenttime+cur->tempruntime;
                sliceAvailable=sliceAvailable-cur->tempruntime; 
                cur->endtime=currenttime;
                cur->waittime=cur->endtime-cur->arrivetime;
                totalWaittime=totalWaittime+cur->waittime;
                cur->state=Finish;
                FinNum++;
                printf("task%d finished.  priority:%d,waittime:%d,runtime:%d,arrivetime:%d\n",cur->tid,cur->priority,cur->waittime,cur->runtime,cur->arrivetime);
                pre->next=cur->next;
                free(cur);
                cur=pre->next;
            }
            else if(cur->tempruntime==sliceAvailable){
printf("t=a %d %d\n",cur->tid,sliceAvailable);
                currenttime=currenttime+cur->tempruntime;
                cur->endtime=currenttime;
                cur->waittime=cur->endtime-cur->arrivetime;
                totalWaittime=totalWaittime+cur->waittime;
                cur->state=Finish;
                FinNum++;   
                printf("task%d finished.  priority:%d,waittime:%d,runtime:%d,arrivetime:%d\n",cur->tid,cur->priority,cur->waittime,cur->runtime,cur->arrivetime);
                pre->next=cur->next;
                free(cur);
                cur=pre->next;
                sliceAvailable=slice;
            }
            else if(cur->tempruntime>sliceAvailable){
printf("t>a %d %d\n",cur->tid,sliceAvailable);
                currenttime=currenttime+sliceAvailable; 
                cur->tempruntime=cur->tempruntime-sliceAvailable;
                cur->state=Waitting;
                //把未结束的移到队尾
                if(cur->next==NULL){
                   
                }else{
                pre->next=cur->next; 
                end->next=cur; 
                end=cur;
                cur->next=NULL;
                cur=pre->next;
                }
                sliceAvailable=slice;
            }
        }
    }
    //printf("threadnum:%d\n",ThreadNum);
    //printf("totalwa:%d\n",totalWaittime);
    printf("RR schedule finished.Average waittime is %d.\n",totalWaittime/ThreadNum);
}

void main(){
    init();
    //FCFS();
    //RR();
    //SJF();
    //Priority();
}

逻辑想清楚之后,主要的操作就是对链表进行的操作。

在RR算法当中,没有运行完的任务被移动到队尾但是并没有将其next指向NULL,于是就导致了最后两个任务无法正常完成。

哼 野指针 大bug 要牢记!

猜你喜欢

转载自blog.csdn.net/xueying_2017/article/details/80426200