OS中的SSTF 和LLF

来源:互联网 发布:linux查看内存信息 编辑:程序博客网 时间:2024/05/21 20:45
//1、SSTF最短寻道时间优先算法磁盘调度


#include <iostream>
using namespace std;


int abs(int a){
return a >=0 ? a : (-a);
}


struct pos{
  int k;    //磁道次序
  int Num;   //磁道号
  int visit;   //访问位,初始都为0,表示未访问
}p[200];




//最短寻道
pos Min(pos currentpos , pos p[], int n){
int nextposNo;
pos minpos;
int MNum=9999;
      for(int i=1; i<=n; i++)
 {
 if( p[i].visit==0)
 {
     int min=abs(p[i].Num-currentpos.Num);
      if( min < MNum )
      {
                MNum=min;
                minpos=p[i];
                nextposNo = i;
                }
 }
 }
p[nextposNo].visit=1;
return minpos;
}




int  main()
{


  int n,i;
  cout<<"请输入磁盘请求队列中的磁道个数:";
  cin>>n;


  cout<<"请依次按到达的次序输入各磁道的磁道号:"<<endl;
  for( i=1; i<=n; i++){
 p[i].visit=0;
 p[i].k = i;
 cin>>p[i].Num;
  }


    pos currentpos;
    cout<<"请输入当前磁道所在的磁道号(默认此当前磁道的访问位为1):";
    cin>>currentpos.Num;
//cout<<"默认此当前磁道的访问位为1"<<endl;
currentpos.visit=1;


int sum=0;
double average=0.0;


//找距离当前磁道找距离最小的磁道号
for(i=1; i<=n ; i++)
{
        pos tmp=Min(currentpos , p, n );
        sum += abs(tmp.Num-currentpos.Num);
        cout<<"被访问的下一个磁道是:"<<tmp.k<<"   "<<"磁道号为:"<<tmp.Num<<"  "
            <<"移动的磁道数是:"<<abs(tmp.Num-currentpos.Num)<<endl;
        currentpos = tmp;
}
average = sum *1.0 / n;
cout<<"总的寻道长度为:"<<sum<<endl;
cout<<"平均寻道长度为:"<<average<<endl;


return 0;
}






/*


运行结果:


请输入磁盘请求队列中的磁道个数: 8
请依次按到达的次序输入各磁道的磁道号:
98
183
37
122
14
67
65
124
请输入当前磁道所在的磁道号(默认此当前磁道的访问位为1):53
被访问的下一个磁道是:7   磁道号为:65  移动的磁道数是:12
被访问的下一个磁道是:6   磁道号为:67  移动的磁道数是:2
被访问的下一个磁道是:3   磁道号为:37  移动的磁道数是:30
被访问的下一个磁道是:5   磁道号为:14  移动的磁道数是:23
被访问的下一个磁道是:1   磁道号为:98  移动的磁道数是:84
被访问的下一个磁道是:4   磁道号为:122  移动的磁道数是:24
被访问的下一个磁道是:8   磁道号为:124  移动的磁道数是:2
被访问的下一个磁道是:2   磁道号为:183  移动的磁道数是:59
总的寻道长度为:236
平均寻道长度为:29.5


Process returned 0 (0x0)   execution time : 24.728 s
Press any key to continue.


*/












//======================================================================
//2、最低松弛度调度算法


#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <math.h>




#define queuesize  10
#define  maxtime   100  //考虑前100s时间


//进行结构体
typedef struct process  //进程
{
    char pname[5];  //进程名
    int  deadtime;  //周期
    int  servetime;     //执行时间
    int  lefttime;      //进程某一次执行到停止的执行时间(考虑到抢占)
    int  cycle;         //执行到的周期数
    int  latestarttime;     //进程下一次最迟开始时间,+currenttime即为松弛度,如果等于currenttime则抢占当前进程
    int  arivetime;          //进程下一次最早开始时间
}process;


typedef struct sqqueue       //循环队列
{
   process *data[queuesize];
    int front,rear;
} sqqueue;


//初始化n个进程
void Initprocess(process *pro,int n)
{
    int i;
    process *p;
    p=pro;
    for(i=0;i<n;i++)
       {
          *(p->pname)='\0';
          p->deadtime=0;
          p->servetime=0;
          p->lefttime=0;
          p->cycle=0;
          p->latestarttime=0;
          p->arivetime=0;
          p++;
       }


}


//初始化队列(队空)
void InitQueue(sqqueue *que)
{
       que->front=que->rear=0;
}


//进程进入循环队列
void  enterQueue(sqqueue *que,process *pro)
{
    //判断循环队列是否已满
    if((que->rear+1)%queuesize==que->front)
        printf("队列已满!\n");
    else
        {
            que->data[que->rear]=pro;//进程放入队尾
            que->rear=(que->rear+1)%queuesize;  //队尾指针加一
            printf("%s",pro->pname);//printf("%d",pro->deadtime);
            printf("成功入队!\n");
        }
}


//从当前队列中找到最低松弛度的进程
process *llf(sqqueue *dui,int currenttime)
{
     sqqueue *q1;
     q1=dui;
     process *currentpro,*pro;
     int front,rear,minllf,llf;


     front=q1->front;
     rear=q1->rear;


     //将队首进程赋给当前进程
     currentpro=q1->data[front];


    //直到找到在当前时间下第一个可以开始执行的进程,赋给pro
    if(currenttime<=100){
     while(front!=rear )
          {
              //先将队首进程赋给进程pro
            pro = q1->data[front];
            // 当进程可在当前时间开始执行,则计算松弛度
            if(pro->arivetime <= currenttime)
                 {
                     //初始最小松弛度=周期*需执行的次数- (上一次)执行的时间 -当前时间
                     minllf=(pro->deadtime)*(pro->cycle)- pro->lefttime - currenttime;
                     printf("%ds时%s%d进程的松弛度为:%d\n",currenttime,pro->pname,pro->cycle,minllf);
                     currentpro=pro;
                     break;
                 }
            else
                  front=(front+1)%queuesize;
          }


     if(front==rear  ) //如果队列中只有一个进程
          {
             return currentpro;
             printf("%ds时%s%d进程的松弛度为:%d\n",currenttime,currentpro->pname,currentpro->cycle,llf);
          }
     else   //进程数目多于一个
          {
              //找当前时间下从第一个可以开始执行的进程(currentpro)之后的进程
               front=(front+1)%queuesize;
               do
                  {
                      if(front!=rear)
                           {
                                pro=q1->data[front];
                                if(pro->arivetime<=currenttime  && currenttime<=100)
                                     {
                                         //计算松弛度
                                         llf=(pro->deadtime)*(pro->cycle)-pro->lefttime-currenttime;
                                         printf("%ds时%s%d进程的松弛度为:%d\n",currenttime,pro->pname,pro->cycle,llf);
                                         if(minllf>llf)  //比较得出最低松弛度
                                            {
                                                minllf=llf;
                                                //currentpro为最低松弛度的进程
                                                currentpro=pro;
                                            }
                                     }
                                front=(front+1)%queuesize;
                           }
                      else
                            break;
                  }while(front!=rear);  //循环队列不空


          }
          //currentpro即为最低松弛度的进程
               return  currentpro;
          }
}


//寻找松弛度<=0 的抢占进程
process  *leastlaxityfirst(sqqueue *dui,int currenttime)
{
    sqqueue *q1;
    process *pro,*nextpro;
    int rear,front;
    q1=dui;
    pro=NULL;
    front=q1->front;
    rear=q1->rear;


   //当队列不空,寻找当前时刻是否有松弛度为0(需抢占进程的进程)
    while(front!=rear)
         {
            nextpro=q1->data[front];
            //当nextpro->latestarttime - currenttime <=0,即松弛度为0时,跳出循环,立即抢占进程
            if(nextpro->latestarttime < currenttime)
                    break;
            else
                front=(front+1)%queuesize;
         }


    if(front==rear)   //如果队列空,返回pro
         return pro;
    //队列不空,nextpro为此时抢占正在执行的进程的进程
    else
         return nextpro;
}


//从队列中读取进程
void shedule(sqqueue *dui)
{
    int currenttime=0;
    static int  starttime, endtime;


    sqqueue *que;
    que=dui;
     int front=que->front;
     int rear=que->rear;


    process *currentpro,*pro;
    //currentpro为队列中松弛度最低的进程
    currentpro=llf(que,currenttime);


    while(currenttime <= maxtime)
          {
              //最低松弛度的进程为空
               if(currentpro==NULL)
                    {
                         printf("无可运行进程!\n");
                         break;
                    }
               else
                    {
                      if((currentpro->arivetime <= currenttime || currenttime==0) &&currenttime!=100 )
                               {
                                   printf("当前时间是:%d    ",currenttime);
                                   currenttime++;  //当前时间增加
                                   currentpro->lefttime--;  //运行剩余时间减少




                                  printf("%s%d进程运行了%d s时间;\n",currentpro->pname,currentpro->cycle,currentpro->servetime-currentpro->lefttime);


                                     //printf("-------------%d—%d 秒: %s%d;\n" ,starttime,endtime,currentpro->pname,currentpro->cycle);


                                    //当运行时间等于当前进程的周期,即当程序运行结束
                                   if(currentpro->lefttime==0)
                                            {
                                                currentpro->cycle++;
                                                 currentpro->lefttime=currentpro->servetime;
                                                 currentpro->arivetime=(currentpro->deadtime)*(currentpro->cycle-1);
                                                 currentpro->latestarttime=(currentpro->deadtime)*(currentpro->cycle)-(currentpro->servetime);
                                                 currentpro=llf(que,currenttime);
                                            }
                                //当进程未运行完毕被抢占。。。
                                   else
                                            {
                                                //pro为抢占当前正执行进程的进程
                                                 pro=leastlaxityfirst(que,currenttime);
                                                 if(pro!=NULL)
                                                     {
                                                         //currentpro为松弛度最小的进程,不论是否是抢占程序
                                                         currentpro=pro;
                                                     }
                                            }


                               }


                               else if( currentpro->arivetime >= currenttime  )
                                {
                                   currenttime++;
                                  if(currenttime!=101) printf("第%d秒时进程未到达!\n",currenttime-1);
                                   currentpro=llf(que,currenttime);
                                  }
                    }
          }
}


int main()
{
  sqqueue *dui,*dui2;
  process *pro,pro2[queuesize],*pro3;
  int front,rear,ci=0,pi=0;
  //int currenttime=0;
  int flag=1,i;
  char ch,ch2,name[5];
  printf("\n");
  printf("***************************最低松弛调度******************************\n");


  printf("\n");
  dui=(sqqueue *)malloc(sizeof(sqqueue));
  dui->rear = dui->front = 0;
  dui2=(sqqueue *)malloc(sizeof(sqqueue));
  dui2->rear=dui2->front=0;
  while(1)
  {  i=0;
     InitQueue(dui) ;
     Initprocess(pro2,queuesize);
     printf("请输入周期进程有关的信息:\n");
     while(flag)
          {
              pro=pro2+i;


            printf("\n请输入进程名(长度小于5):");
            gets(name);
            strcpy(pro->pname,name);


            printf("\n请输入进程的周期:");
            scanf("%d",&(pro->deadtime));
            getchar();


            printf("\n请输入进程的执行时间:");
            scanf("%d",&(pro->servetime)); getchar();
            pro->lefttime=pro->servetime; //
            pro->cycle=1;     //初始时进程执行到第一周期
            pro->latestarttime=(pro->deadtime)*(pro->cycle)-pro->servetime;  //进程下一次执行的时间
            pro->arivetime=(pro->deadtime)*(pro->cycle-1);  // 进程下一次开始的最早时间
            enterQueue(dui,pro);    //进队列
            i++;  //进程个数


            printf("\n是否继续进程信息的输入(0:结束,1:继续):");
            scanf("%d",&flag); getchar();
          }


     dui2=dui;
     front=dui2->front;
     rear=dui2->rear;


     while(front!=rear)
         {
              pro3=dui2->data[front];
              ci=pro3->servetime+ci;  //各进程执行的时间总和
              pi=pro3->deadtime+pi;    //各周期总和
              front=(front+1)%queuesize;
         }
     if((ci/pi)<=1)
          {
              shedule(dui);
              printf("进程运行完毕!\n");
              printf("\n");
              printf("是否要结束使用(Y/N)?");
              scanf("%c",&ch); getchar();
              if ('Y'==toupper(ch))
                 {


                    printf("\n   任意键结束!   ");
                    scanf("%c",&ch2);
                    exit(0);
                 }
             else
                    flag=1;
          }
     else
          {
              printf("所输入的进程不满足要求!    ");
              printf("\n是否重新输入(Y/N):\n");
              scanf("%c",&ch); getchar();
              if ('N'==toupper(ch))
                 {
                     printf("请按任意键结束\n");
                     exit(0);
                 }
          }


  }
  return 0;


}




/*
运行结果是:


***************************最低松弛调度******************************


请输入周期进程有关的信息:


请输入进程名(长度小于5):A


请输入进程的周期:20


请输入进程的执行时间:10
A成功入队!


是否继续进程信息的输入(0:结束,1:继续):1


请输入进程名(长度小于5):B


请输入进程的周期:50


请输入进程的执行时间:10
B成功入队!


是否继续进程信息的输入(0:结束,1:继续):1


请输入进程名(长度小于5):C


请输入进程的周期:50


请输入进程的执行时间:15
C成功入队!


是否继续进程信息的输入(0:结束,1:继续):0
0s时A1进程的松弛度为:10
0s时B1进程的松弛度为:40
0s时C1进程的松弛度为:35
当前时间是:0    A1进程运行了1 s时间;
当前时间是:1    A1进程运行了2 s时间;
当前时间是:2    A1进程运行了3 s时间;
当前时间是:3    A1进程运行了4 s时间;
当前时间是:4    A1进程运行了5 s时间;
当前时间是:5    A1进程运行了6 s时间;
当前时间是:6    A1进程运行了7 s时间;
当前时间是:7    A1进程运行了8 s时间;
当前时间是:8    A1进程运行了9 s时间;
当前时间是:9    A1进程运行了10 s时间;
10s时B1进程的松弛度为:30
10s时C1进程的松弛度为:25
当前时间是:10    C1进程运行了1 s时间;
当前时间是:11    C1进程运行了2 s时间;
当前时间是:12    C1进程运行了3 s时间;
当前时间是:13    C1进程运行了4 s时间;
当前时间是:14    C1进程运行了5 s时间;
当前时间是:15    C1进程运行了6 s时间;
当前时间是:16    C1进程运行了7 s时间;
当前时间是:17    C1进程运行了8 s时间;
当前时间是:18    C1进程运行了9 s时间;
当前时间是:19    C1进程运行了10 s时间;
当前时间是:20    C1进程运行了11 s时间;
当前时间是:21    C1进程运行了12 s时间;
当前时间是:22    C1进程运行了13 s时间;
当前时间是:23    C1进程运行了14 s时间;
当前时间是:24    C1进程运行了15 s时间;
25s时A2进程的松弛度为:5
25s时B1进程的松弛度为:15
当前时间是:25    A2进程运行了1 s时间;
当前时间是:26    A2进程运行了2 s时间;
当前时间是:27    A2进程运行了3 s时间;
当前时间是:28    A2进程运行了4 s时间;
当前时间是:29    A2进程运行了5 s时间;
当前时间是:30    A2进程运行了6 s时间;
当前时间是:31    A2进程运行了7 s时间;
当前时间是:32    A2进程运行了8 s时间;
当前时间是:33    A2进程运行了9 s时间;
当前时间是:34    A2进程运行了10 s时间;
35s时B1进程的松弛度为:5
当前时间是:35    B1进程运行了1 s时间;
当前时间是:36    B1进程运行了2 s时间;
当前时间是:37    B1进程运行了3 s时间;
当前时间是:38    B1进程运行了4 s时间;
当前时间是:39    B1进程运行了5 s时间;
当前时间是:40    B1进程运行了6 s时间;
当前时间是:41    B1进程运行了7 s时间;
当前时间是:42    B1进程运行了8 s时间;
当前时间是:43    B1进程运行了9 s时间;
当前时间是:44    B1进程运行了10 s时间;
45s时A3进程的松弛度为:5
当前时间是:45    A3进程运行了1 s时间;
当前时间是:46    A3进程运行了2 s时间;
当前时间是:47    A3进程运行了3 s时间;
当前时间是:48    A3进程运行了4 s时间;
当前时间是:49    A3进程运行了5 s时间;
当前时间是:50    A3进程运行了6 s时间;
当前时间是:51    A3进程运行了7 s时间;
当前时间是:52    A3进程运行了8 s时间;
当前时间是:53    A3进程运行了9 s时间;
当前时间是:54    A3进程运行了10 s时间;
55s时B2进程的松弛度为:35
55s时C2进程的松弛度为:30
当前时间是:55    C2进程运行了1 s时间;
当前时间是:56    C2进程运行了2 s时间;
当前时间是:57    C2进程运行了3 s时间;
当前时间是:58    C2进程运行了4 s时间;
当前时间是:59    C2进程运行了5 s时间;
当前时间是:60    C2进程运行了6 s时间;
当前时间是:61    C2进程运行了7 s时间;
当前时间是:62    C2进程运行了8 s时间;
当前时间是:63    C2进程运行了9 s时间;
当前时间是:64    C2进程运行了10 s时间;
当前时间是:65    C2进程运行了11 s时间;
当前时间是:66    C2进程运行了12 s时间;
当前时间是:67    C2进程运行了13 s时间;
当前时间是:68    C2进程运行了14 s时间;
当前时间是:69    C2进程运行了15 s时间;
70s时A4进程的松弛度为:0
70s时B2进程的松弛度为:20
当前时间是:70    A4进程运行了1 s时间;
当前时间是:71    A4进程运行了2 s时间;
当前时间是:72    A4进程运行了3 s时间;
当前时间是:73    A4进程运行了4 s时间;
当前时间是:74    A4进程运行了5 s时间;
当前时间是:75    A4进程运行了6 s时间;
当前时间是:76    A4进程运行了7 s时间;
当前时间是:77    A4进程运行了8 s时间;
当前时间是:78    A4进程运行了9 s时间;
当前时间是:79    A4进程运行了10 s时间;
80s时A5进程的松弛度为:10
80s时B2进程的松弛度为:10
当前时间是:80    A5进程运行了1 s时间;
当前时间是:81    A5进程运行了2 s时间;
当前时间是:82    A5进程运行了3 s时间;
当前时间是:83    A5进程运行了4 s时间;
当前时间是:84    A5进程运行了5 s时间;
当前时间是:85    A5进程运行了6 s时间;
当前时间是:86    A5进程运行了7 s时间;
当前时间是:87    A5进程运行了8 s时间;
当前时间是:88    A5进程运行了9 s时间;
当前时间是:89    A5进程运行了10 s时间;
90s时B2进程的松弛度为:0
当前时间是:90    B2进程运行了1 s时间;
当前时间是:91    B2进程运行了2 s时间;
当前时间是:92    B2进程运行了3 s时间;
当前时间是:93    B2进程运行了4 s时间;
当前时间是:94    B2进程运行了5 s时间;
当前时间是:95    B2进程运行了6 s时间;
当前时间是:96    B2进程运行了7 s时间;
当前时间是:97    B2进程运行了8 s时间;
当前时间是:98    B2进程运行了9 s时间;
当前时间是:99    B2进程运行了10 s时间;
100s时A6进程的松弛度为:10
100s时B3进程的松弛度为:40
100s时C3进程的松弛度为:35
进程运行完毕!


是否要结束使用(Y/N)?


*/