操作系统——动态优先级调度算法源代码

类别:编程语言 点击:0 评论:0 推荐:

    多道系统中多进程并发执行,为了提高系统性能解决进程死锁问题,进程的优先级是动态变化的。正在执行的进程优先级会随时间降低,而挂起的进程或等待的进程的优先级会逐渐升高,这样就解决了操作系统中一个地优先级程序长期占据cpu,而高优先级进程却迟迟不能得到处理。
    这是我最近使用tc2.0图形界面对该算法进行模拟的源代码,所有代码都放在一个文件里了。
    今天发现有的blog转载了本blog的文章,我非常欢迎,但请您注明转载自这里,这样也为我的blog做一下广告,谢谢!
#include <time.h>
#include <dos.h>
#include <math.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <graphics.h>

#define ESC 0x1b
#define ENTER 0x0d
#define TRUE 1
#define FALSE 0
/*每隔TIME秒就变换一次优先级*/
#define TIME 5

 

/*数据结构*/
/****************************************************************/
enum _Status/*进程状态枚举*/
{
 READY =0,/*就绪*/
 RUN,/*执行中*/
 SUSPEND,/*挂起*/
};
typedef enum _Status Status;
/****************************************************************/
struct _Pcb/*进程结构*/
{
 int  PID;/*进程ID,ID为负数的进程为系统后备队列的作业*/
 int  Time;/*进程运行需要的时间*/
 int  Prior;/*进程的优先级,越大越优先*/
 Status  Sts;/*状态*/
 struct _Pcb *Next;/*指向本进程队列中下个进程的PCB*/
};
typedef struct _Pcb PCB;
/****************************************************************/
struct _Batch/*多道处理中的道结构*/
{
 PCB  *pcb;/*该道当前正在处理的进程*/
 struct _Batch *Next;/*下一道*/
};
typedef struct _Batch Batch;
/****************************************************************/
/*多道系统相关全局变量*/
PCB *ProcQueue = NULL;/*进程链表,按优先级从大到小排列*/
Batch *BatchQueue = NULL;/*系统多道链表*/
/****************************************************************/

 


/*动态优先权抢占式调度算法及相关函数声明*/
/****************************************************************/
int InitBatchs(int n);/*初始化多道系统,n为道数*/
int InsertProc(int prior, int time);/*向进程链表中按优先级大小插入一个新进程*/
int InsertIDLE();/*向进程队列中加入后备进程,当系统空闲时将被调入*/
int SortProcQueue();/*将进程链表按优先级从大到小排列*/
int AddBatch();/*增加系统道数*/
int DeleteBatch();/*减少系统道数*/
int UnSuspendProc(int id);/*解除ID为id的进程的挂起状态*/
int UpdateBatchs();/*多道系统根据进程链表进行更新,并将执行完毕的进程删除*/
int PassSeconds(int n);/*系统经过n秒后计算数据并进行优先级调度*/
/****************************************************************/

 


/*各函数的定义*/
/****************************************************************/
int InitBatchs(int n)
{
 int i;
 for (i=0; i<n; ++i)
 {
  AddBatch();
 }
 return (UpdateBatchs());
}

int InsertProc(int prior, int time)
{
 static int sysid = 0;/*该系统已经加入过多少进程,此值将是新进程的ID*/
 PCB *last,*now,*pcb;
 pcb = (PCB*)malloc(sizeof(PCB));
 if (pcb == NULL) return FALSE;
 pcb->Prior = prior;
 pcb->Time = time;
 pcb->PID = (++sysid);
 pcb->Sts = READY;
 if (ProcQueue == NULL)/*如果进程队列为空*/
 {
  ProcQueue = pcb;
  pcb->Next = NULL;
  return TRUE;
 }
 last = ProcQueue;
 now = last->Next;

 if (pcb->Prior > last->Prior)/*pcb将排在队头*/
 {
  pcb->Next = ProcQueue;
  ProcQueue = pcb;
  return TRUE;
 }
 while ((now != NULL) && (pcb->Prior < now->Prior))/*寻找插入位置*/
 {
  last = now;
  now = last->Next;
 }
 last->Next = pcb;
 pcb->Next = now;
 return TRUE;
}

int InsertIDLE()
{
 PCB *now = ProcQueue;
 PCB *idle = (PCB*)malloc(sizeof(PCB));
 if (idle == NULL) return FALSE;
 idle->PID = -1;
 idle->Prior = -1;
 idle->Sts = SUSPEND;
 idle->Time = -1;
 idle->Next = NULL;
 if (ProcQueue == NULL)
 {
  ProcQueue = idle;
  return TRUE;
 }
 while(now->Next != NULL)
 {
  now = now->Next;
 }
 now->Next = idle;
 return TRUE;
}

int SortProcQueue()
{ /*冒泡排序*/
 PCB *last, *now;
 int b = FALSE;/*上次遍历是否无交换产生*/
 if (ProcQueue==NULL || ProcQueue->Next==NULL)/*如果链表中无进程或只有一个进程*/
  return FALSE;
 while (!b)
 {
  b = TRUE;
  last=ProcQueue;
  now=last->Next;
  if (last->Prior < now->Prior)
  {
   ProcQueue = now;
   last->Next = now->Next;
   now->Next = last;
   b = FALSE;
   last = ProcQueue;
   now = last->Next;
  }
  while (now->Next!=NULL)
  {
   if ((now->Prior)<(now->Next->Prior))
   {
    last->Next = now->Next;
    now->Next = now->Next->Next;
    last->Next->Next = now;
    b = FALSE;
   }
   else
    last = last->Next;
   now = last->Next;
  }
 }
 return TRUE;
}

int AddBatch()
{
 Batch *bt = (Batch*)malloc(sizeof(Batch));
 if (bt==NULL) return FALSE;
 bt->Next = BatchQueue;
 BatchQueue = bt;
 bt->pcb = NULL;
 return (InsertIDLE());
}

int DeleteBatch()
{
 Batch *bt = BatchQueue;
 PCB *last, *now;
 if (BatchQueue==NULL || BatchQueue->Next==NULL)/*如果只剩最后一道则不删除*/
  return FALSE;
 if (ProcQueue==NULL || ProcQueue->Next==NULL)/*如果只有最后一个后备空闲进程*/
  return FALSE;/**/
 last = ProcQueue;
 now = last->Next;
 while (now->Next != NULL)/*查找到最后一个进程,该进程必定是后备空闲进程*/
 {
  last = now;
  now = last->Next;
 }
 if (now==NULL || now->PID>=0)/*未查找到后备进程*/
  return FALSE;/**/
 free(now);
 last->Next = NULL;
 BatchQueue = BatchQueue->Next;
 free(bt);
 return TRUE;
}

int UnSuspendProc(int id)
{
 PCB *now = ProcQueue;
 if (ProcQueue==NULL) return FALSE;
 while (now != NULL)
 {
  if (now->PID == id)
  {
   now->Sts = READY;
   return TRUE;
  }
 }
 return FALSE;
}

int UpdateBatchs()
{
 Batch *bt = BatchQueue;
 PCB *last = ProcQueue, *now;
 while (bt != NULL)
 {
  bt->pcb = NULL;
  bt = bt->Next;
 }
 if (ProcQueue == NULL) return TRUE;
 while (last->Sts==RUN && last->PID>=0 && last->Time<=0)
 {
  ProcQueue = ProcQueue->Next;
  free(last);
  last = ProcQueue;
 }
 now = last->Next;
 while (now != NULL)
 {
  if (now->Sts==RUN && now->PID>=0 && now->Time<=0)/*如果该进程是运行中的一般进程并已执行完毕*/
  {
   last->Next = now->Next;
   free(now);
  }
  else
   last = last->Next;
  now = last->Next;
 }
 bt = BatchQueue;
 now = ProcQueue;
 while (bt != NULL && now != NULL)
 {
  bt->pcb = now;
  now->Sts = RUN;
  bt = bt->Next;
  now = now->Next;
 }
 while (now != NULL)
 {
  if (now->Sts == RUN)
  {
   now->Sts = SUSPEND;
  }
  now = now->Next;
 }
 return TRUE;
}

int PassSeconds(int n)
{
 static int time = 0;
 int i=0, ProcEnd = FALSE;
 PCB *pcb = ProcQueue;
 Batch *bt = BatchQueue;
 if (bt == NULL) return FALSE;
 time += n;
 if (time>=TIME)
 {
  i = time/TIME;/*经过多少时间段*/
  time = time%TIME;
 }
 while (bt != NULL)/*更新进程运行时间*/
 {
  if (bt->pcb->PID>=0)
  {
   bt->pcb->Time -= n;
   if (bt->pcb->Time <= 0)/*进程结束*/
   {
    ProcEnd = TRUE;
   }
  }
  bt = bt->Next;
 }
 if (i > 0)
 {
  while (pcb != NULL)/*更新进程优先权(动态优先权)*/
  {
   if (pcb->Sts == RUN && pcb->PID>=0)/*运行的进程优先权降低*/
   {
    pcb->Prior -= i;
    if (pcb->Prior < 0)
     pcb->Prior = 0;
   }
   else if (pcb->Sts == SUSPEND && pcb->PID>=0)/*挂起的进程优先权升高*/
    pcb->Prior += i;
   pcb = pcb->Next;
  }
 }
 if (i>0)
  SortProcQueue();/*如果优先级有变动则重新排序*/
 if (ProcEnd || i>0)
 {
  UpdateBatchs();/*更新多道进程*/
 }
 return TRUE;
}
/****************************************************************/

 


/*图形界面相关函数*/
/****************************************************************/
/*表格的单位宽度和高度*/
#define WIDTH 64
#define HEIGHT 12
void *black=NULL;/*背景色方格,使用它擦出表格中的图形*/
int InitGraph()/*初始化图形界面*/
{
 int    GraphDriver;  /* The Graphics device driver  */
 int    GraphMode;  /* The Graphics mode value  */
 int ErrorCode;
 GraphDriver = DETECT;   /* Request auto-detection */
 initgraph( &GraphDriver, &GraphMode, "" );
 ErrorCode = graphresult();  /* Read result of initialization*/
 if( ErrorCode != grOk )
 {  /* Error occured during init */
  printf(" Graphics System Error: %s\n", grapherrormsg( ErrorCode ) );
  getch();
  return FALSE;
 }
 cleardevice();
 black = (void*)malloc(imagesize(1,1,WIDTH-1,HEIGHT-1));
 getimage(1,1,WIDTH-1,HEIGHT-1,black);
 DrawFrame();
 DrawData();
 return TRUE;
}
int DrawFrame()/*画边框和表头*/
{
 settextjustify(CENTER_TEXT, CENTER_TEXT);
 gprintf(320, HEIGHT/2-1, "Multi-Batch System Emulation");
 settextjustify(LEFT_TEXT, TOP_TEXT);
 moveto(0,HEIGHT);
 lineto(0,479);
 lineto(639,479);
 lineto(639,HEIGHT);
 lineto(0,HEIGHT);
 line(WIDTH*4,HEIGHT,WIDTH*4,479);
 line(WIDTH*7,HEIGHT,WIDTH*7,479);
 line(0,HEIGHT*2,639,HEIGHT*2);
 line(0,HEIGHT*3,639,HEIGHT*3);
 gprintf(HEIGHT*0+2,HEIGHT*1+2,"System Batchs");/*系统多道列表头*/
 gprintf(HEIGHT*0+2,HEIGHT*2+2,"Batch");
 gprintf(WIDTH*1+2,HEIGHT*2+2,"ProcID");
 gprintf(WIDTH*2+2,HEIGHT*2+2,"Time");
 gprintf(WIDTH*3+2,HEIGHT*2+2,"Prior");
 gprintf(WIDTH*4+2,HEIGHT*1+2,"Suspended Processes");/*挂起队列列表头*/
 gprintf(WIDTH*4+2,HEIGHT*2+2,"ProcID");
 gprintf(WIDTH*5+2,HEIGHT*2+2,"Time");
 gprintf(WIDTH*6+2,HEIGHT*2+2,"Prior");
 gprintf(WIDTH*7+2,HEIGHT*1+2,"Ready Processes");/*就绪队列列表头*/
 gprintf(WIDTH*7+2,HEIGHT*2+2,"ProcID");
 gprintf(WIDTH*8+2,HEIGHT*2+2,"Time");
 gprintf(WIDTH*9+2,HEIGHT*2+2,"Prior");
}
int DrawData()/*绘制系统数据*/
{
 int numRun=0, numSus=0, numRed=0;/*运行挂起和就绪的进程各有多少*/
 PCB* now = ProcQueue;
 int x=0, y=0;
 while (now != NULL)
 {
  switch(now->Sts)
  {
  case RUN:
   x = WIDTH*1;
   y = HEIGHT*(3+(numRun++));
   break;
  case SUSPEND:
   x = WIDTH*4;
   y = HEIGHT*(3+(numSus++));
   break;
  case READY:
   x = WIDTH*7;
   y = HEIGHT*(3+(numRed++));
   break;
  }
  if (now->Sts==RUN)/*该进程为正在运行的进程*/
  {
   putimage(x-WIDTH+1,y+1,black,COPY_PUT);
   gprintf(x-WIDTH+2,y+2,"%d",numRun);
  }
  if (now->PID>=0)/*该进程不是后备进程*/
  {
   putimage(x+1,y+1,black,COPY_PUT);
   gprintf(x+2,y+2,"%d",now->PID);
   putimage(x+1+WIDTH,y+1,black,COPY_PUT);
   gprintf(x+WIDTH+2,y+2,"%d",now->Time);
   putimage(x+1+WIDTH*2,y+1,black,COPY_PUT);
   gprintf(x+WIDTH*2+2,y+2,"%d",now->Prior);
  }
  else
  {
   putimage(x+1,y+1,black,COPY_PUT);
   putimage(x+1+WIDTH,y+1,black,COPY_PUT);
   putimage(x+1+WIDTH*2,y+1,black,COPY_PUT);
   gprintf(x+2,y+2,"system idle process");
  }
  now = now->Next;
 }
}
int DlgGetNum(char *buf,int l,int t,int r,int b,int gettime)
{
 char ch;
 int pos=0;
 bar(l,t,r,b);
 gprintf(l+10,t+5,"Add new Process");
 if (gettime)
  gprintf(l+10,t+20,"input the time:");
 else
  gprintf(l+10,t+20,"input the priority:");
 while (1)
 {
  ch = getch();
  if (ch == ENTER)/*如果输入了回车键*/
  {
   if(pos!=0)/*如果位置不在第一位(回车键不准第一个输入)*/
   {
    buf[pos]='\0';
    break;
   }
  }
  else if (ch>='0' && ch<='9')
  {
   buf[pos++]=ch;
   buf[pos]='\0';
  }
  else if (ch == ESC)
  {
   return FALSE;
  }
  else/*其他按键均按BackSpace处理*/
  {
   --pos;
   buf[pos]='\0';
  }
  if (pos<0)
  { pos=0; buf[pos]='\0';}
  else if (pos>4)/*最多输入4位数*/
  { pos=4; buf[pos]='\0';}
  bar(l,t+35,r,t+47);
  gprintf(l+50,t+35,buf);
 }
 return TRUE;
}
int NewProcDlg()
{
 int l=200,t=150,r=380,b=200,pos=0,prior=0,time=0;
 char buf[5],ch;
 PCB *pcb;
 void* bg = (void*)malloc(imagesize(l,t,r,b));
 getimage(l,t,r,b,bg);
 setfillstyle(1,2);
 flushall();
 /*******输入优先级**********/
 if (!DlgGetNum(buf,l,t,r,b,FALSE))
  goto exit;
 prior = atoi(buf);
 /*******输入时间**********/
 pos=0;
 buf[pos]='\0';
 if (!DlgGetNum(buf,l,t,r,b,TRUE))
  goto exit;
 time = atoi(buf);
 InsertProc(prior, time);
exit:
 putimage(l,t,bg,COPY_PUT);
 free(bg);
 return TRUE;
}
int gprintf( int xloc, int yloc, char *fmt, ... )/*图形系统中的格式输出*/
{
  va_list  argptr;   /* Argument list pointer */
  char str[140];   /* Buffer to build sting into */
  int cnt;    /* Result of SPRINTF for return */

  va_start( argptr, format );  /* Initialize va_ functions */

  cnt = vsprintf( str, fmt, argptr ); /* prints string to buffer */
  outtextxy( xloc, yloc, str ); /* Send string in graphics mode */

  va_end( argptr );   /* Close va_ functions  */

  return( cnt );   /* Return the conversion count */
}
/****************************************************************/

 

/*main函数*/
int main()
{
 clock_t start=0, end=0;
 char kb;
 InitBatchs(3);/*初始化为3道系统*/
 InitGraph();
 while (1)
 {
  start = end = clock();
  while (!kbhit())
  {
   start = clock();
   if ((start-end)/18.2 >= 1)/*时间过了一秒*/
   {
    start = end = clock();
    PassSeconds(1);
    cleardevice();
    DrawFrame();
    DrawData();
   }
  }
  kb = getch();
  switch (kb)
  {
  case ESC:
   closegraph();
   return 0;
  case 'w':
   AddBatch();
   UpdateBatchs();
   cleardevice();
   DrawFrame();
   DrawData();
   break;
  case 's':
   DeleteBatch();
   UpdateBatchs();
   cleardevice();
   DrawFrame();
   DrawData();
   break;
  case 'i':
   NewProcDlg();
   UpdateBatchs();
   DrawFrame();
   DrawData();
   break;
  }
 }
 return 0;
}

本文地址:http://com.8s8s.com/it/it24922.htm