定义一个结构体来模拟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 要牢记!