模拟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 要牢记!

好的,我可以为你介绍一下CPU调度算法以及如何模拟实现。 CPU调度算法是操作系统中的一个重要概念,它决定了在多道程序环境下,操作系统如何分配CPU时间片给进程,以达到最优的性能。常见的CPU调度算法有以下几种: 1. 先来先服务(FCFS):按照进程到达的先后顺序进行调度,不考虑进程的优先级和执行时间,容易导致短作业等待时间过长,长作业等待时间过短的问题。 2. 最短作业优先(SJF):按照进程执行时间的长短进行调度,优先执行执行时间短的进程,容易导致长作业等待时间过长的问题。 3. 优先级调度:按照进程优先级进行调度,优先执行优先级高的进程,容易导致低优先级进程长时间等待的问题。 4. 时间片轮转(RR):按照时间片的大小进行调度,每个进程都分配一个时间片,时间到后切换到下一个进程,可以保证所有进程公平地分配CPU时间。 要模拟实现这些调度算法,可以通过编写一个模拟调度程序来实现。具体步骤如下: 1. 定义进程的数据结构,包括进程ID、到达时间、执行时间、优先级等。 2. 定义一个就绪队列,将到达时间小于当前时间的进程加入队列中。 3. 根据不同的调度算法,从就绪队列中选择下一个要执行的进程。 4. 执行所选择的进程,并更新该进程的信息,例如执行时间、优先级等。 5. 如果进程执行完毕,则从就绪队列中移除该进程。 6. 重复步骤3~5,直到所有进程执行完毕。 通过模拟调度程序的实现,可以更好地理解和掌握CPU调度算法的原理和应用。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值