操作系统常见算法(主要模块)

来源:互联网 发布:php源码如何传到服务器 编辑:程序博客网 时间:2024/06/03 16:09

写在前面的话

这些算法,是我自己近几天在网上搜索下来,并通过自己调试。下列的各个算法,仅是每个算法最核心的部分。

如果需要源代码,可以私信我。 (内存分配、EDF还未写上)


高响应比调度算法



voidhighestResponseRatioNext(struct JCB* jcb){

      createJCB(jcb); // 其实就是对所列数据结构进行初始化赋值

      compare(jcb); //按到达时间排序

      int i = 0, j = 0;

      for(; finishNumber != JOBNUMBER;currentTime++){

             float maxPriority = 0.0;

             int indexPriority = 0;

             if(currentTime <jcb[0].arriveTime)//当前时间小于第一个节点到来时间时,直接打印

                    printJob(jcb);

             else{

                    for(int i = 0; i < JOBNUMBER; i++){

                           if(strcmp(jcb[i].processStatus,FINISH) != 0){

                                  int waitTime = currentTime -jcb[i].arriveTime;

                                priority[i] = (waitTime + jcb[i].runTime) * 1.0 /jcb[i].runTime;

                                if(priority[i] >maxPriority){

                                       maxPriority = priority[i];

                                       indexPriority = i;

                                }

                                                 

                    }

                    strcpy(JobArray[j++], jcb[indexPriority].jobName);

                    loop(jcb, indexPriority);  //见下面一个函数

             }

      }

      printInfo(jcb);//打印进程调度顺序,平均周转时间及平均带权周转时间

      currentTime = 0;//当前时间置位

      finishNumber = 0;//完成进程数量置位

}

 

void loop(struct JCB* jcb,int i){

      jcb[i].startTime = currentTime;

      jcb[i].endTime = jcb[i].startTime + jcb[i].runTime;

      jcb[i].turnoverTime = jcb[i].endTime -jcb[i].arriveTime;

      jcb[i].useWeightTurnoverTime = jcb[i].turnoverTime * 1.0 /jcb[i].runTime;

      strcpy(jcb[i].processStatus, RUN);

      while(true){

             if(currentTime ==jcb[i].endTime){     

                    strcpy(jcb[i].processStatus, FINISH);

                    finishNumber++;

                    if(finishNumber ==JOBNUMBER)

                           printJob(jcb); 

                    currentTime--;

                    break;

             }

             else{

                    printJob(jcb);

                    currentTime++; 

                 

      }

}


先来先服务

voidfirstComeFirstServed(structJCB* jcb){

      createJCB(jcb);

      compare(jcb);

      int i = 0;

      //进程调度currentTime每次加1,直到进程全部被调度完成为止

      for(; finishNumber != JOBNUMBER;currentTime++){

             if(currentTime <jcb[0].arriveTime)//当前时间小于第一个节点到来时间时,直接打印

                    printJob(jcb);

             else{

                    strcpy(JobArray[i], jcb[i].jobName);

                    loop(jcb, i); //见上一个函数

                    i++;

             }

      }

      printInfo(jcb);//打印进程调度顺序,平均周转时间及平均带权周转时间

      currentTime = 0;//静态变量当前时间置位

      finishNumber = 0;//静态变量完成进程数量置位

}

时间片轮转调度算法

typedef struct pcb{

      char id[10];//进程标识数

      int arrivetime;//到达时间

      int runtime;//进程已经占用的cpu时间

      int needtime;//进程还需要的时间

      char state[12];//进程运行状态:wait or runing

      struct pcb *next;

}pcb,*PCB;

 

voidRR_RunProcess(){

      //运行进程,简单轮转法Round Robin

      PCB p,q,temp;

      p=head->next;

      while(1){

      if(head->next==NULL)

      {

             printf("此时就绪队列中已无进程!\n");

                    return ;

      }

      else

      {

             while(p){

                    if((p->needtime>0)&&!(strcmp(p->state,"wait")))

                    {

                           printf("进程%s开始,\n",p->id);

                           strcpy(p->state,"run");

                           p->runtime+=TIME;

                           p->needtime-=TIME;      

                           if(p->needtime<0)

                                  p->needtime=0;

                    }

                     temp=p;//把该时间片内运行完的进程存到临时temp

 

                     //temp接到链表尾部,销毁P

                     if(temp->needtime>0){//把该时间片内运行完的进程接到就绪队列的尾部

                            if(count>1)

                            {

                                   head->next=temp->next;

                                   tail->next=temp;

                                   tail=tail->next;

                                   strcpy(tail->state,"wait");

                                   tail->next=NULL;

                            }

                            else if(count==1)

                             

                                   //当只有一个进程等待时,分开讨论

                                   head->next=temp;

                                   tail=temp;

                                   strcpy(tail->state,"wait");

                                   tail->next=NULL;

                            }               

                    }

                     if(temp->needtime==0){//销毁就绪队列中已经结束的进程

                            count--;//此时就绪队列中进程数减1

                            printf("进程%s结束.\n",p->id);

                            head->next=temp->next;

                            free(temp);//撤销就绪队列中已经结束的进程

                     }

                   p=head->next;

             }

      }

      }

}

 

 

银行家算法

typedefstruct {
int
A;
int
B;
int
C;
}RESOURCE;

 

//最大需求矩阵

RESOURCEMax[PROCESSES_NUMBER] =

{

   {7,5,3},

   {3,2,2},

   {9,0,2},

   {2,2,2},

   {4,3,3}

};

 

 

//已分配资源数矩阵

RESOURCEAllocation[PROCESSES_NUMBER] =

{

   {0,1,0},

   {2,0,0},

   {3,0,2},

   {2,1,1},

   {0,0,2}

};

 

//需求矩阵

RESOURCENeed[PROCESSES_NUMBER] =

{

   {7,4,3},

   {1,2,2},

   {6,0,0},

   {0,1,1},

   {4,3,1}

};

 

//可用资源向量

RESOURCEAvailable = {3,3,2};

//试探分配

voidProbeAlloc(int process,RESOURCE *res)

{

   Available.A -= res->A;

   Available.B -= res->B;

   Available.C -= res->C;

 

   Allocation[process].A += res->A;

   Allocation[process].B += res->B;

   Allocation[process].C += res->C;

 

   Need[process].A -= res->A;

   Need[process].B -= res->B;

   Need[process].C -= res->C;

}

 

//若试探分配后进入不安全状态,将分配回滚

voidRollBack(int process,RESOURCE *res)

{

   Available.A += res->A;

   Available.B += res->B;

   Available.C += res->C;

 

   Allocation[process].A -= res->A;

   Allocation[process].B -= res->B;

   Allocation[process].C -= res->C;

 

   Need[process].A += res->A;

   Need[process].B += res->B;

   Need[process].C += res->C;

}

boolSafeCheck()

{

   RESOURCE    Work= Available;

   bool       Finish[PROCESSES_NUMBER] ={false,false,false,false,false};

   int       i;

   int       j = 0;

 

    for(i = 0; i < PROCESSES_NUMBER; i++)

   {

       //该进程是否已执行完毕

       if(Finish[i] == false)

       {

           //是否有足够的资源分配给该进程

           if(Need[i].A <= Work.A && Need[i].B <= Work.B&& Need[i].C <= Work.C)

           {

               //有则使其执行完成,并将已分配给该进程的资源全部回收

               Work.A += Allocation[i].A;

               Work.B+= Allocation[i].B;

               Work.C += Allocation[i].C;

               Finish[i] = true;

               safeSeq[j++] = i;  //顺便记录下来安全序列

               i =-1;               //需要从开始重新进行遍历

           }

       }

   }

 

   //如果所有进程的Finish向量都为true则处于安全状态,否则为不安全状态

    for(i = 0; i < PROCESSES_NUMBER; i++)

   {

       if (Finish[i] == false)

       {

           return false;

       }

   }

   return true;

}

//资源分配请求

boolrequest(int process,RESOURCE *res)

{

   //request向量需小于Need矩阵中对应的向量

   if(res->A <= Need[process].A && res->B <=Need[process].B && res->C <=Need[process].C)

   {

       //request向量需小于Available向量

       if(res->A <= Available.A && res->B <=Available.B && res->C <= Available.C)

       {

           //试探分配

           ProbeAlloc(process,res);

 

           //如果安全检查成立,则请求成功,否则将分配回滚并返回失败

           if(SafeCheck())

           {

               return true;

           }

           else

           {

               printf("安全性检查失败。原因:系统将进入不安全状态,有可能引起死锁。\n");

               printf("正在回滚...\n");

               RollBack(process,res);

           }

       }

       else

       {

           printf("安全性检查失败。原因:请求向量大于可利用资源向量。\n");

       }

   }

   else

   {

       printf("安全性检查失败。原因:请求向量大于需求向量。\n");

   }

   return false;

}

 

 

 

页面调度算法

int fifo(MemBlock *pb,intm)

{

  intlps=0;  

  doublelpp;  

  int p =0;   

  intindex =0; 

  while(index

     if(!in_mem(page[index],pb,M)){   //如果该页面不在物理块中

       pb[p].pagenum =page[index];       

       p =(p+1)%M;                    

       lps++;                          

       for(int i=0;i

         result[i][index] = pb[i].pagenum;

       }

     }

     index++;

  }

  printf("FIFO算法所得缺页次数为 %d\n",lps);

  lpp = (double)lps/PAGES;

  printf("FIFO算法缺页率为 %0.4lf \n",lpp);

  printf("页面号序列为:\n");

  printArr1(page,PAGES);

  printf("结果数列为:\n");

  printRelArr(result);

  return0;

}

 


LRU算法

int getP(MemBlock *pb,intp)

{

  inti;

  bool out= true//

  for(i=0;i

   if(pb[i].recenttime ==-1){

     p = i;

     out = false;

     break;

   }

  }

  if(out){

   for(i=0;i

     if(pb[i].recenttime>pb[p].recenttime)

       p = i;

   }

  }

  returnp;

}

 

int getEQnum(int num,MemBlock*pb)

{

  inti;

  int in =-1;

  for(i=0;i

   if(pb[i].pagenum ==num){

     in = i;

     break;

   }

  }

  returnin;

}

 

 

void lru(MemBlock *pb,intm)

{

  intlps=0;  

  doublelpp;  

  int p =0;   

  intindex =0; 

  while(index

     if(!in_mem(page[index],pb,m)){  

       p = getP(pb,p);   

       pb[p].pagenum = page[index];

       pb[p].recenttime = 0;

       lps++;

       for(int i=0;i

         result[i][index] = pb[i].pagenum;

       }

     }else                       

       int in =getEQnum(page[index],pb); 

         pb[in].recenttime = 0;

     }

     int i;

     for(i=0;i

         if(i!=p&&pb[i].recenttime!=-1){

           pb[i].recenttime++;

         }

     }

     index++;

  }

  printf("LRU算法所得缺页次数为 %d \n",lps);

  lpp = 1.0*lps/PAGES;

  printf("LRU算法缺页率为: %0.4lf\n",lpp);

  printf("页面号序列为:\n");

  printArr1(page,PAGES);

  printf("LRU结果数组为:\n");

  printRelArr(result);

}

原创粉丝点击