农村散养土鸽子视频:C语言模拟CPU调度

来源:百度文库 编辑:偶看新闻 时间:2024/04/29 12:22:06

C语言模拟CPU调度

                                      

CPU在处理多个进程时,要根据各种情况对处理的进程进行调度。这其中就包括对各个进程优先级的处理,和调度算法的处理。下面这个C语言程序,是我在大学期间学习《操作系统》课程的CPU调度时编写的,模拟了CPU的两种调度模式和各种模式所对应的多种调度算法。为了模拟得更为形象,采用了图形屏幕输出。
#include
#include
#include
#include
#include
#include
#define  NULL  0
/*-----------------------------------------------------------------*/
struct event            /*事件结点结构*/
{
 int evtype;         /*1:进程产生。2:进程执行。3:激活阻塞进程。
                 4:进程执行完 5:进程阻塞* 6:返回事件*/
 int pnum;           /*执行该事件的进程号*/
    int t;              /*事件发生的时间*/
 int ifblock;   /*如果是执行事件标准其有无阻塞,其它事件时无定义*/
 struct event *next;
};
struct process              /*进程结点结构*/
{
 int pnum;               /*进程号*/
 int plong;              /*进程长度*/
 int prior;              /*进程优先级*/
 int blocknum;           /*进程当前的阻塞数*/
 int runtime;            /*执行次数*/
 struct process *next;
};
struct headnod              /*队列头结点结构*/
{
 struct process *head;   /*队列头*/
 int    totalpro;        /*队列中的进程数*/
 struct process *tail;   /*队列尾*/
};
/*=================================================================*/
int    Mode,Algorithm;        /*选择的调度模式和算法*/
struct event *evhead;         /*事件链表的头结点*/
struct headnod *ready,*block; /*就绪队列、阻塞队列的头结点*/
main()
{
 int    gdriver,gmode;
 struct process *runpro=NULL;   /*当前正在执行的进程*/
    struct process *wakepro;      /*当前被唤醒的进程*/
 struct process *newpro;       /*新建进程*/
 int    busy=0;                /*标志cpu状态*/
 menu();                       /*选择调度模式和算法的菜单*/
    gdriver=DETECT;
    initgraph(&gdriver, &gmode, "");
    setbkcolor(LIGHTBLUE);
    cleardevice(); welcome();                /*显示欢迎屏幕*/
    start();                  /*初始化*/
    while(evhead!=NULL)
 {
  switch(evhead->evtype)
  {
    case 1:                 /*产生新进程并在就绪队列中排队*/
     {
          randomize();
             newpro=(struct process *)malloc(sizeof(struct process));
                 newpro->pnum=evhead->pnum;
                 newpro->plong=rand()%3+1;
                 if((Mode==2)&&(Algorithm==2))
                 newpro->prior=rand()%3+1;
                 else
                 newpro->prior=0;   /*优先级相等*/
                    if((Mode==2)&&(Algorithm==1))
     {
              newpro->runtime=newpro->plong+1;
        newpro->blocknum=rand()%2;
     }
                 else
     {
                  newpro->blocknum=rand()%3;
      newpro->runtime=1;
     }
                 newpro->next=NULL;
                 drawcreate(newpro); /*画出产生一个新进程*/
        Orderp(1,newpro);
        drawQ(1);
        sleep(1);
        if(ready->head==newpro)
     {
      if(busy==0)
            Runevent();
      else
       if((Mode==2)&&(Algorithm==2)&&(newpro->prior>runpro->prior))
       {
        Interupt(runpro);
        returnev(runpro);
       }
     }
     }
     break;
    case 2:                 /*执行事件*/
     {
        runpro=ready->head;
     ready->head=ready->head->next;
     runpro->next=NULL;
     ready->totalpro--;
     busy=1;
     Run(runpro);           /*画进入cpu*/
     drawQ(1);
     sleep(1);
        if(evhead->ifblock==1)
        blockev(runpro);    
        else
     {
           runpro->runtime--;
          if(runpro->runtime==0)
          overev(runpro);     /*产生结束事件*/
           else
          returnev(runpro);  
     }    
     }
     break;
     case 3:                             /*激活事件*/
      {
      wakepro=block->head;
      block->head=block->head->next;
      wakepro->next=NULL;
      block->totalpro--;
      wakeup(wakepro);/*移动激活进程*/
      if(block->totalpro!=0)
      {
                     drawQ(2);
         sleep(1);
      }
      Orderp(1,wakepro);
      drawQ(1);
      sleep(1);                   if(ready->head==wakepro)
     {
      if(busy==0)
            Runevent();
      else
       if((Mode==2)&&(Algorithm==2)&&(wakepro->prior>runpro->prior))
       {
        Interupt(runpro);
        returnev(runpro);
       }
     }      wakepro=NULL;
     if(block->totalpro!=0)
        wakeupev();
      }
     break;
    case 4:                            /*结束事件*/
     {
      over(runpro);
      runpro=NULL;
      busy=0;
      if(ready->totalpro!=0)
     Runevent();
     }
      break;
    case 5:                          /*阻塞事件*/
     {
    blocked(runpro);
    busy=0;
    if(ready->totalpro!=0)
     Runevent();
     Orderp(2,runpro);
     drawQ(2);
     sleep(1);
     if(block->head==runpro)
     wakeupev();
     runpro=NULL;
     }
     break;
    case 6:                        /*返回事件*/
     {
                returnwait(runpro); /*画出返回*/
    busy=0;
    Orderp(1,runpro);
    runpro=NULL;
    drawQ(1);
    sleep(1);
    Runevent();
     }
     break;
  }
         evhead=evhead->next;
 } setcolor(LIGHTRED);
 settextstyle(1,0,0);
 setusercharsize(1, 1, 2, 1);
 outtextxy(290,340,"END!");
 setcolor(15);
    settextstyle(1,0,1);
outtextxy(105,420,"Author : ZHOUWUBO   CLASS : 01-1   NO.17");
 getch();
 getch();
    closegraph();
}
/*=================================================================*/
menu()  /*选择菜单*/
{
    char wrong;
    textbackground(LIGHTBLUE);
    clrscr();
 window(20,3,60,23);
 textbackground(LIGHTRED);
    textcolor(YELLOW);
    clrscr();
   gotoy(2,2);
   cprintf("Please select the Scheduling Mode:");
   gotoxy(5,3);
   cprintf("1.Non-Preemptive");
   gotoxy(5,4);
   cprintf("2.Preemptive");
   gotoxy(7,5);
   cprintf(">> ");
   cscanf("%d",&Mode);
   switch(Mode)
   {
     case 1:
   {
           gotoxy(2,7);
        cprintf("Please select the Scheduling Algorithm:");
     gotoxy(5,8);
        cprintf("1.FCFS");
     gotoxy(5,9);
     cprintf("2.SPF");
     gotoxy(7,10);
        cprintf(">> ");
        cscanf("%d",&Algorithm);
     if((Algorithm!=1)&&(Algorithm!=2))
     {
       gotoxy(2,12);
       cprintf("Your select is wrong! Run once again!");
       scanf("%c",&wrong);
     }
     break;
   }
  case 2:
   {
              gotoxy(2,7);
        cprintf("Please select the Scheduling Algorithm:");
     gotoxy(5,8);
        cprintf("1.Round Robin");
     gotoxy(5,9);
     cprintf("2.Priority");
     gotoxy(7,10);
        cprintf(">> ");
        cscanf("%d",&Algorithm);
     if((Algorithm!=1)&&(Algorithm!=2))
     {
       gotoxy(2,12);
       cprintf("Your select is wrong! Run once again!");
       scanf("%c",&wrong);
     }
     break;
   }
  default:
   {
    gotoxy(2,7);
    cprintf("Your select is wrong! Run once again!");
    scanf("%c",&wrong);
   }
   }
}
/*-----------------------------------------------------------------*/
welcome()        /*显示欢迎屏幕*/
{
    int i;
       setcolor(14);
    outtextxy(45,178,"create");
    outtextxy(40,188,"process");
    outtextxy(555,210,"Finish");
    line(100,204,170,204);
    line(170,204,160,199);
    line(160,199,165,204);
    line(100,226,170,226);
    line(170,226,160,231);
    line(160,231,165,226);
    rectangle(370,40,420,60);
    rectangle(425,40,475,60);
    rectangle(480,40,530,60);
    rectangle(535,40,588,60);
    setcolor(LIGHTRED);
    if((Mode==1)&&(Algorithm==1))
    {
  int arw[8]={395,62,385,77,405,77,395,62};
     setlinestyle(0, 0, 3);
     drawpoly(4,arw);
    }
    if((Mode==1)&&(Algorithm==2))
    {
  int arw[8]={450,62,440,77,460,77,450,62};
     setlinestyle(0, 0, 3);
     drawpoly(4,arw);
    }
    if((Mode==2)&&(Algorithm==1))
    {
  int arw[8]={505,62,495,77,515,77,505,62};
     setlinestyle(0, 0, 3);
     drawpoly(4,arw);
    }
    if((Mode==2)&&(Algorithm==2))
    {
  int arw[8]={561,62,551,77,571,77,561,62};
     setlinestyle(0, 0, 3);
     drawpoly(4,arw);
    }
    setlinestyle(0, 0, 1);
    settextstyle(2,0,7);
    outtextxy(373,40,"FCFS");
    outtextxy(434,40,"SPF");
    outtextxy(495,40,"RR");
    settextstyle(2,0,5);
    outtextxy(537,42,"Priorty");
    settextstyle(1,0,0);
    setusercharsize(1, 1, 2, 1);
    outtextxy(82,18, "CPU SCHEDULING");
    outtextxy(280,360,"start!");        setcolor(14);
  line(220,204,230,204);
  line(230,204,230,200);
  line(230,200,380,200);
  line(380,200,380,204);
  line(380,204,390,204);
  line(390,204,424,180);
  line(424,180,424,170);
  line(456,180,456,100);
  line(456,100,180,100);
  line(180,100,180,204);
  line(180,204,175,194);
  line(175,194,180,199);
  line(456,180,490,204);
  line(490,204,510,204);
  settextstyle(1,0,1);
  outtextxy(275,180,"READY");
  line(220,226,230,226);
  line(230,226,230,230);
  line(230,230,380,230);
  line(380,230,380,226);
  line(380,226,390,226);
  line(390,226,424,250);
  line(424,250,424,260);
  line(456,250,456,330);
  line(456,330,410,330);
  line(410,330,410,334);
  line(410,334,260,334);
  line(260,334,260,330);
  line(260,330,180,330);
  line(180,330,180,226);
  line(180,226,175,236);
  line(175,236,180,231);
  line(420,308,410,308);
  line(410,308,410,304);
  line(410,304,260,304);
  line(260,304,260,308);
  line(260,308,250,308);
  line(456,250,490,226);
  line(490,226,510,226);
  outtextxy(305,285,"BLOCK");
  circle(440,215,30);
  sleep(2);
  setcolor(LIGHTBLUE);
  for(i=0;i<=43;i++)
  {
   line(280+i,360,280+i,420);
   line(365-i,360,365-i,420);
   delay(5000);
  }
 }
/*-----------------------------------------------------------------*/
start() /*初始化*/
{
 int i;
 int t;
 struct event *p1,*p2;
 p1=(struct event *)malloc(sizeof(struct event));
   p1->evtype=1;
   p1->pnum=1;
   p1->t=0;
   p1->ifblock=0; /*在进程产生事件中无意义*/
   p1->next=NULL;
    t=p1->t;
 evhead=p1;
 randomize();
 for(i=2;i<=5;i++)
 {
      p2=(struct event *)malloc(sizeof(struct event));
   p2->evtype=1;
   p2->pnum=i;
   p2->t=t+rand()%2+1;
      p2->ifblock=0;
   p2->next=NULL;
   t=p2->t;
   p1->next=p2;
   p1=p1->next;
 }
ready=(struct headnod*)malloc(sizeof(struct headnod));
   ready->head=NULL;
   ready->totalpro=0;
   ready->tail=NULL;
block=(struct headnod*)malloc(sizeof(struct headnod));
   block->head=NULL;
   block->totalpro=0;
   block->tail=NULL;
}
/*-----------------------------------------------------------------*/
drawcreate(struct process *p) /*画出进程的产生过程*/
{
 void *buf;
 int i,size;
   setfillstyle(1,p->pnum);
   bar(56,206,55+10*p->plong,224);
   size=imagesize(55,205,56+10*p->plong,225);
      buf=malloc(size);
      getimage(55,205,56+10*p->plong,225,buf);
      for(i=0; i<134; i++)
   {
        putimage(55+i,205,buf,COPY_PUT);
  delay(3500);
   }
   free(buf);
}
/*-----------------------------------------------------------------*/
Orderp(int flag,struct process *p)/*1:就绪队列排队 2:阻塞队列排队*/
{
 struct process *q;
 if(flag==1) /*就绪队列*/
 {
     if(ready->totalpro==0)
  {
   ready->head=p;
   ready->tail=p;
   ready->totalpro++;
  }
  else
  {
     if((Mode==1)&&(Algorithm==1)) /*FCFS*/
     {
          ready->tail->next=p;
       ready->tail=ready->tail->next;
       ready->totalpro++;
     }
           if((Mode==1)&&(Algorithm==2))  /*短进程优先*/
     {
             if(p->plonghead->plong) /*长度小于当前队头*/
    {
         p->next=ready->head;
         ready->head=p;
         ready->totalpro++;
    }
          else   /*长度大于当前队头*/
    {
                 q=ready->head;
          while(q->next!=NULL)
    {
                  if(p->plongnext->plong)
      {
        p->next=q->next;
        q->next=p;
        ready->totalpro++;
        break;
      }
           else
         q=q->next;
    }
          if(q->next==NULL)
    {
         q->next=p;
         ready->totalpro++;
         ready->tail=p;
    }
    }
     }
           if((Mode==2)&&(Algorithm==1)) /*时间片轮转*/
     {
          ready->tail->next=p;
       ready->tail=ready->tail->next;
       ready->totalpro++;
     }
           if((Mode==2)&&(Algorithm==2)) /*抢占优先级*/
     {
             if(p->prior>ready->head->prior) /*优先级高于当前队头*/
    {
         p->next=ready->head;
         ready->head=p;
         ready->totalpro++;
    }
          else   /*优先级低于当前队头*/
    {
                 q=ready->head;
          while(q->next!=NULL)
    {
                  if(p->prior>q->next->prior)
      {
        p->next=q->next;
        q->next=p;
        ready->totalpro++;
        break;
      }
         else
        q=q->next;
    }
          if(q->next==NULL)
    {
         q->next=p;
         ready->totalpro++;
         ready->tail=p;
    }
    }
     }
  }
 }
 if(flag==2) /*阻塞队列*/
 {
  if(block->totalpro==0)
  {
   block->head=p;
   block->totalpro++;
   block->tail=p;
  }
  else
  {
    block->tail->next=p;
    block->tail=block->tail->next;
    block->totalpro++;
  }
 }
}
/*-----------------------------------------------------------------*/
drawQ(int flag)   /*画出队列,flag=1:就绪队列,flag=2:阻塞队列*/
{
 int i,j;
 struct process *p;
 if(flag==1)
 {
  setcolor(LIGHTBLUE);
  for(i=0;i<=150;i++)
    line(230+i,205,230+i,225);
  for(i=0;i<=30;i++)
    line(189+i,203,189+i,227);       p=ready->head;
    j=379;
   for(i=1;i<=ready->totalpro;i++)
   {
       setfillstyle(1,p->pnum);
       bar(j,206,j-10*p->plong+1,224);
     j=j-10*p->plong-1;
     p=p->next;
   }
 }
    if(flag==2)
 {
       setcolor(LIGHTBLUE);
    for(i=0;i<=150;i++)
     line(260+i,309,260+i,39);
    for(i=0;i<=30;i++)
  line(420+i,308,420+i,329);       p=block->head;
    j=261;
   for(i=1;i<=block->totalpro;i++)
   {
       setfillstyle(1,p->pnum);
       bar(j,309,j+10*p->plong-1,328);
     j=j+10*p->plong+1;
     p=p->next;
   }
 }
}
/*-----------------------------------------------------------------*/
Runevent() /*产生执行事件*/
{
  struct event   *p1;
  struct process *p;
  p=ready->head;
  randomize();
p1=(struct event *)malloc(sizeof(struct event));
    p1->evtype=2;
 p1->pnum=p->pnum;
 p1->t=evhead->t;
 if(p->blocknum!=0)
 {
   p1->ifblock=rand()%2;
   if(p1->ifblock==1)
     p->blocknum--;
 }
 else
   p1->ifblock=0;
 p1->next=NULL;
   Orderev(p1);
}
/*-----------------------------------------------------------------*/
Interupt(struct process *p)     /*中断当前正在执行的进程*/
{
 struct event *q1,*q2;
 if(evhead->next==NULL)
 {
  if(evhead->evtype==4)
   p->runtime++;
     evhead=NULL;
 }
 else
 {
      q1=evhead->next;
   q2=evhead;
 }
 while(q1!=NULL)
 {
  if(q1->pnum==p->pnum)
  {
   if(q1->evtype==4)
     p->runtime++;
   q2->next=q1->next;
   break;
  }
  else
  {
   q2=q1;
            q1=q1->next;
  }
 }
}
/*-----------------------------------------------------------------*/
Orderev(struct event *q) /*在事件链表中插入结点*/
{
 struct event *p;
 p=evhead;
 while(p->next!=NULL)
 {
  if(q->tnext->t)
  {
   q->next=p->next;
   p->next=q;
   break;
  }
  else
   p=p->next;
 }
 if(p->next==NULL)
  p->next=q;
}
/*----------------------------------------------------------------*/
blockev(struct process *p) /*产生阻塞事件*/
{
  struct event *q;
  randomize();
  q=(struct event *)malloc(sizeof(struct event));
     q->evtype=5;
  q->pnum=p->pnum;
  q->t=evhead->t+rand()%4+2;
     q->ifblock=0;
  q->next=NULL;
  Orderev(q);
}
/*-----------------------------------------------------------------*/
blocked(struct process *p)  /*画出阻塞过程*/
{
 int i,size;
 void *buf;
   setcolor(LIGHTBLUE);
   for(i=1;i<=28;i++)
   circle(440,215,i);
   setfillstyle(1,p->pnum);
   bar(426,251,426+10*p->plong-2,269);
   size=imagesize(425,250,426+10*p->plong-1,270);
      buf=malloc(size);
      getimage(425,250,426+10*p->plong-1,270,buf);
      for(i=0; i<59; i++)
   {
        putimage(425,250+i,buf,COPY_PUT);
  delay(3500);
   }
   for(i=0;i<5;i++)
   {
        putimage(425-i,308,buf,COPY_PUT);
  delay(3500);
   }
     free(buf);
}
/*-----------------------------------------------------------------*/
wakeupev()          /*产生唤醒事件*/
{
 struct event *q;
 struct process *p;
 p=block->head;
 randomize();
 q=(struct event *)malloc(sizeof(struct event));
   q->evtype=3;
   q->pnum=p->pnum;
   q->t=evhead->t+rand()%3+4;
   q->ifblock=0; /*此时无意义*/
   q->next=NULL;
    Orderev(q);
}
/*-----------------------------------------------------------------*/
Run(struct process *p) /*画出执行*/
{
 int i,size;
 void *buf;
 size=imagesize(380,205,380-10*p->plong-1,225);
      buf=malloc(size);
      getimage(380,205,380-10*p->plong-1,225,buf);
      for(i=0; i<29; i++)
   {
        putimage(380-10*p->plong-1+i,205,buf,COPY_PUT);
     delay(3500);
   }
   setcolor(LIGHTBLUE);
   for(i=0;i<29;i++)
    line(380+i,205,380+i,225);
   setcolor(p->pnum);
   for(i=1;i<=28;i++)
   circle(440,215,i);
   free(buf);
}
/*-----------------------------------------------------------------*/
overev(struct process *p) /*产生结束事件*/
{
  struct event *q;
  randomize();
  q=(struct event *)malloc(sizeof(struct event));
     q->evtype=4;
  q->pnum=p->pnum;
  if((Mode==2)&&(Algorithm==1))
   q->t=evhead->t+2;   /*时间片为2*/
  else
   q->t=evhead->t+3*(p->plong);/*时间由进程长度确定*/
     q->ifblock=0;
  q->next=NULL;
  Orderev(q);
}
/*-----------------------------------------------------------------*/
returnev(struct process *p)      /*产生返回事件*/
{
 struct event *q;
 randomize();
 q=(struct event *)malloc(sizeof(struct event));
     q->evtype=6;
  q->pnum=p->pnum;
  if((Mode==2)&&(Algorithm==2))
   q->t=evhead->t;
  else
    q->t=evhead->t+2;   /*时间片为2*/
     q->ifblock=0;
  q->next=NULL;
  Orderev(q);
}
/*-----------------------------------------------------------------*/
wakeup(struct process *p)/*画出唤醒过程*/
{
    int i,size;
 void *buf;
 size=imagesize(260,309,261+10*p->plong,329);
      buf=malloc(size);
      getimage(260,309,261+10*p->plong,329,buf);
      for(i=0; i<72; i++)
   {
        putimage(260-i,309,buf,COPY_PUT);
     delay(3500);
   }
   for(i=0;i<104;i++)
   {
        putimage(189,309-i,buf,COPY_PUT);
     delay(3500);
   }
   free(buf);
}
/*-----------------------------------------------------------------*/
returnwait(struct process *p)/*画出返回过程*/
{
    int i,size;
 void *buf;
      setcolor(LIGHTBLUE);
   for(i=1;i<=28;i++)
   circle(440,215,i);
   setfillstyle(1,p->pnum);
   bar(426,161,426+10*p->plong-2,179);
   size=imagesize(425,160,426+10*p->plong-1,180);
      buf=malloc(size);
      getimage(425,160,426+10*p->plong-1,180,buf);
      for(i=0; i<59; i++)
   {
        putimage(425,160-i,buf,COPY_PUT);
  delay(3500);
   }
   for(i=0;i<237;i++)
   {
        putimage(425-i,101,buf,COPY_PUT);
  delay(3500);
   }
   for(i=0;i<105;i++)
   {
        putimage(189,101+i,buf,COPY_PUT);
  delay(3500);
   }
    free(buf);
}
/*-----------------------------------------------------------------*/
over(struct process *p) /*画出结束过程*/
{
   int i,size;
   void *buf;
   int k=evhead->pnum;
      setcolor(LIGHTBLUE);
   for(i=1;i<=28;i++)
   circle(440,215,i);
   setfillstyle(1,k);
   bar(476,206,476+10*p->plong,224);
   size=imagesize(475,205,476+10*p->plong+1,225);
      buf=malloc(size);
      getimage(475,205,476+10*p->plong+1,225,buf);
      for(i=0; i<=45; i++)
   {
        putimage(475+i,205,buf,COPY_PUT);
  delay(4000);
   }
   setcolor(LIGHTBLUE);
   for(i=0;i<=31;i++)
   {
    line(520+i,205,520+i,225);
    delay(4000);
   }
   free(buf);
}