最近比较忙,难得更新blog,下星期二就开始期末考试了,还要准备英语六级,忙死了。 这是帮别人做的程序,模拟操作系统中进程控制块(包括多道系统中动态优先级进程调度和动态内存分配),用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 BACKSPACE 8 #define TRUE 1 #define FALSE 0 typedef unsigned UINT; /*每隔TIME秒就变换一次优先级*/ #define TIME 5 /*系统的总内存容量(BYTE),暂定为32KB*/ #define TOTALMEM (UINT)((UINT)1024*(UINT)32) /*系统本身占用内存大小(BYTE),暂定为2KB*/ #define SYSMEM (UINT)(2048) /*系统后备空闲进程占用内存大小(BYTE),暂定为1KB*/ #define IDLEMEM (UINT)(1024)
/*多道系统数据结构*/ /****************************************************************/ enum _ProcStatus/*进程状态枚举*/ { READY =0,/*就绪*/ RUN,/*执行中*/ SUSPEND,/*挂起*/ }; typedef enum _ProcStatus ProcStatus; /****************************************************************/ enum _MemStatus/*内存分区块状态枚举*/ { IDLE =0,/*空闲中*/ INUSE,/*使用中*/ }; typedef enum _MemStatus MemStatus; /****************************************************************/ struct _MemBlock/*内存分区块结构*/ { UINT Offset;/*起始地址*/ UINT Size;/*内存块大小(以BYTE为单位)*/ MemStatus Sts;/*内存分区块使用状态*/ struct _MemBlock *Next;/*内存块列表中下一个内存块*/ }; typedef struct _MemBlock MemBlock; /****************************************************************/ struct _Pcb/*进程结构*/ { int PID;/*进程ID,ID为负数的进程为系统后备队列的作业*/ int Time;/*进程运行需要的时间*/ int Prior;/*进程的优先级,越大越优先*/ ProcStatus Sts;/*状态*/ MemBlock *Mem;/*所使用的内存块*/ struct _Pcb *Next;/*指向本进程队列中下个进程的PCB*/ }; typedef struct _Pcb PCB; /****************************************************************/ struct _Batch/*多道处理中的道结构*/ { PCB *pcb;/*该道当前正在处理的进程*/ struct _Batch *Next;/*下一道*/ }; typedef struct _Batch Batch; /****************************************************************/ /*系统相关全局变量*/ PCB *ProcQueue = NULL;/*进程链表,按优先级从大到小排列*/ MemBlock *MemTable = NULL;/*内存分区表,按起始地址从小到大排序*/ MemBlock *SysMem = NULL;/*系统本身占用的内存分区*/ Batch *BatchQueue = NULL;/*系统多道链表*/ /****************************************************************/
/*动态优先权抢占式调度算法及相关函数声明*/ /****************************************************************/ int InitBatchs(int n);/*初始化多道系统,n为道数*/ int InsertProc(int prior, int time, UINT size);/*向进程链表中按优先级大小插入一个新进程*/ int InsertIDLE();/*向进程队列中加入后备进程,当系统空闲时将被调入*/ int SortProcQueue();/*将进程链表按优先级从大到小排列*/ int AddBatch();/*增加系统道数*/ int DeleteBatch();/*减少系统道数*/ int UnSuspendProc(int id);/*解除ID为id的进程的挂起状态*/ int UpdateBatchs();/*多道系统根据进程链表进行更新,并将执行完毕的进程删除*/ int PassSeconds(int n);/*系统经过n秒后计算数据并进行优先级调度*/ /****************************************************************/ /*可变大小内存分区算法及相关函数声明*/ /****************************************************************/ int InitMem();/*初始化内存分区表,sysmemsize是系统占据的内存大小*/ MemBlock* ApplyMem(UINT size);/*进程向系统申请内存*/ int ReleaseMem(MemBlock* mem);/*进程pcb结束要求释放内存*/ int MergeMem();/*整理内存表,相邻的空闲分区将归并为一份*/ /****************************************************************/
/*各函数的定义*/ /****************************************************************/ int InitBatchs(int n) { int i; for (i=0; i<n; ++i) { if (!AddBatch()) return FALSE; } return (UpdateBatchs()); }
int InsertProc(int prior, int time, UINT size) { static int sysid = 0;/*该系统已经加入过多少进程,此值将是新进程的ID*/ PCB *last,*now,*pcb; MemBlock *mem; if (prior<=0 || time<=0 || size<=0) return FALSE; mem = ApplyMem(size); if (mem == NULL) return FALSE; pcb = (PCB*)malloc(sizeof(PCB)); if (pcb == NULL) return FALSE; pcb->Prior = prior; pcb->Time = time; pcb->PID = (++sysid); pcb->Sts = READY; pcb->Mem = mem; 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; MemBlock *mem = ApplyMem(IDLEMEM); PCB *idle; if (mem==NULL) return FALSE; 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; idle->Mem = mem; 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;/**/ ReleaseMem(now->Mem);/*释放进程的内存*/ free(now); last->Next = NULL; BatchQueue = BatchQueue->Next; free(bt); return TRUE; }
int UnSuspendProc(int id) { PCB *now = ProcQueue; if (id<=0) return FALSE; if (ProcQueue==NULL) return FALSE; while (now != NULL) { if (now->PID == id) { now->Sts = READY; return TRUE; } now = now->Next; } 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; ReleaseMem(last->Mem); free(last); last = ProcQueue; } now = last->Next; while (now != NULL) { if (now->Sts==RUN && now->PID>=0 && now->Time<=0)/*如果该进程是运行中的一般进程并已执行完毕*/ { last->Next = now->Next; ReleaseMem(now->Mem); 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; } /****************************************************************/ int InitMem() { MemTable = (MemBlock*)malloc(sizeof(MemBlock));/*初始化为只有一个分区*/ if (MemTable==NULL) return FALSE; MemTable->Offset = 0; MemTable->Size = TOTALMEM; MemTable->Sts = IDLE; MemTable->Next = NULL; SysMem = ApplyMem(SYSMEM);/*申请系统本身占用的内存*/ if (SysMem == NULL) { free(MemTable); return FALSE; } return TRUE; }
MemBlock* ApplyMem(UINT size) { MemBlock *mem = NULL, *last,*now; if (MemTable == NULL) return NULL; last = MemTable; now = last->Next; if (last->Sts == IDLE)/*如果第一分区是空闲的*/ { if (last->Size > size)/*该分区可以分出空间*/ { mem = (MemBlock*)malloc(sizeof(MemBlock)); if (mem == NULL) return NULL; mem->Next = last; mem->Offset = last->Offset; mem->Size = size; mem->Sts = INUSE; last->Offset = mem->Offset+mem->Size; last->Size = last->Size-size; MemTable = mem; return mem; } else if (last->Size == size) { mem = last; mem->Sts = INUSE; MemTable = mem; return mem; } } while (now != NULL)/*在分区表中查找可分配内存的空闲分区*/ { if (now->Sts == IDLE) { if (now->Size > size) { mem = (MemBlock*)malloc(sizeof(MemBlock)); mem->Offset = now->Offset; mem->Size = size; mem->Next = now; mem->Sts = INUSE; last->Next = mem; now->Offset = mem->Offset+mem->Size; now->Size = now->Size-size; return mem; } else if (now->Size == size) { mem = last; mem->Sts = INUSE; return mem; } } last = now; now = last->Next; } return NULL; }
int ReleaseMem(MemBlock *mem) { MemBlock *last,*now; if (MemTable==NULL) return FALSE; last = MemTable; now = last->Next; if (last == mem)/*如果第一个就是要释放的分区*/ { last->Sts = IDLE; if (now!=NULL && now->Sts==IDLE)/*如果后邻接分区也是空闲的*/ { last->Size = last->Size+now->Size; free(now); } return TRUE; } while (now!=NULL)/*在链表中寻找要释放的分区*/ { if (now == mem)/*找到了*/ { now->Sts = IDLE; if (now->Next != NULL && now->Next->Sts==IDLE)/*察看后相邻分区是否空闲*/ { last->Next = now->Next; now->Next->Offset = now->Offset; now->Next->Size = now->Size + now->Next->Size; free(now); now = last->Next; } if (last->Sts == IDLE)/*察看前相邻分区是否空闲*/ { last->Next = now->Next; last->Size = last->Size + now->Size; free(now); now = last->Next; } return TRUE; } last = now; now = last->Next; } return FALSE; } /****************************************************************/ /*图形系统相关函数声明及全局变量定义*/ /****************************************************************/ #define HEIGHT 11 #define WIDTH 20 #define HN(n) HEIGHT*(n) #define HNT(n) HEIGHT*(n)-1 /****************************************************************/ int InitGraph();/*初始化图形系统*/ int DrawProcHeader(int x, int y);/*在x,y处绘制进程控制块表头结构*/ int DrawProcStruct(int x, int y, PCB* pcb);/*在x,y处绘制进程控制块pcb数据*/ int DrawAllProc();/*绘制进程列表*/ int DrawFrame();/*绘制图形框架*/ int DrawMemStruct(int x, int y, MemBlock* mem);/*绘制分区mem的数据*/ int DrawMemTable();/*绘制分区表*/ int DrawConsole();/*绘制控制台*/ int DrawConsoleHelp();/*绘制控制台帮助信息*/ int DrawConsoleEcho();/*绘制控制台命令提示符*/ int gprintf( int xloc, int yloc, char *fmt, ... );/*图形系统中的格式输出*/ /****************************************************************/ /*系统控制台(用户接口)相关函数声明及相关全局变量*/ /****************************************************************/ enum _ConsoleCmd/*从系统控制台输入的命令枚举*/ { CMD_EXIT =0,/*退出系统*/ CMD_PAUSE,/*系统时间暂停*/ CMD_PROC,/*加入新的进程*/ CMD_READY,/*将某个挂起进程转入就绪队列*/ CMD_HIBAT,/*增加道数*/ CMD_LOBAT,/*减少道数*/ }; typedef enum _ConsoleCmd ConsoleCmd; /****************************************************************/ char StrCmd[][6]={"exit\0","pause\0","proc\0","ready\0","hibat\0","lobat\0"}; char CmdString[30]; /****************************************************************/ int InitConsole();/*初始化控制台*/ ConsoleCmd GetConsoleCmd();/*从控制台输入缓冲得到用户命令*/ UINT GetData(int n);/*得到第n个数据参数(n>=1)*/ int ExecuteCmd();/*分析命令并得到命令*/ int CmdKeyDown(char ch);/*命令缓冲得到新的键盘输入*/ /****************************************************************/ int main() { clock_t start=0, end=0; char ch; if (!InitConsole()) { printf("can;t initialize console");getch(); return FALSE; } if (!InitMem()) { printf("can't initialize memory");getch(); return FALSE; } if (!InitBatchs(3)) { printf("can't initialize system batchs");getch(); return FALSE; } if (!InitGraph()) { printf("can't initialize graphics system");getch(); return FALSE; } DrawFrame(); DrawAllProc(); DrawMemTable(); DrawConsole(); DrawConsoleHelp(); while (TRUE) { start = end = clock(); while (!kbhit()) { start = clock(); if ((start-end)/18.2 >= 1)/*时间过了一秒*/ { start = end = clock(); DrawConsoleEcho(); PassSeconds(1); DrawAllProc(); DrawMemTable(); } } ch = getch(); if (ch == ESC) return TRUE; if ((ch>='0' && ch<='9')/*如果字符是数字*/ || (ch>='A' && ch<='Z') || (ch>='a' && ch<='z')/*或是字母*/ || (ch==ENTER)/*如果是回车*/ || (ch==' ')/*是空格*/ || (ch==BACKSPACE)/*是退格*/ ) { if (CmdKeyDown(ch)==FALSE)/*如果执行了exit命令*/ return TRUE; else if (ch==ENTER)/*如果执行了命令*/ { DrawAllProc(); DrawMemTable(); } DrawConsole(); } } return TRUE; } 
|