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

来源:互联网 发布:人力资源管理知乎 编辑:程序博客网 时间:2024/06/18 04:16

摘要:

多道系统中多进程并发执行,为了提高系统性能解决进程死锁问题,进程的优先级是动态变化的。正在执行的进程优先级会随时间降低,而挂起的进程或等待的进程的优先级会逐渐升高,这样就解决了操作系统中一个地优先级程序长期占据cpu,而高优先级进程却迟迟不能得到处理。
   这是我最近使用tc2.0图形界面对该算法进行模拟的源代码,所有代码都放在一个文件里了。

#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 12void *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;}

原创粉丝点击