分享
 
 
 

操作系统——PCB模拟代码

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

最近比较忙,难得更新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;

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有