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