上期的笔记,浏览快1万了,既然关注的人很多,那就发出来承诺过的算法全模拟,希望帮到你们。
一、模拟进程调度
功能
data.h
-
#ifndef _Data_h_
-
#define _Data_h_
-
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <string.h>
-
-
#define ElemType PCB
-
#define Status int
-
#define OK 1
-
#define ERROR 0
-
#define TimeSlice 1
-
#define Infinity 10 //INT_MAX
-
-
-
#define NAME_MAXSIZE 20
-
typedef
enum
-
{
-
Ready,Running,Block
-
}ProState;
-
-
typedef
enum
-
{
-
FCFS, SPF
//先来先服务,短进程优先
-
}PriorityRule;
-
-
typedef
struct
-
{
-
char Name[NAME_MAXSIZE];
//进程名
-
int Priority;
//优先数
-
int ArrivalTime;
//到达时间 以时间片为单位
-
int NeedRunningTime;
//运行时间 以时间片为单位
-
int StartTime;
//开始执行时间
-
int FinishTime;
//完成时间
-
int TimeUsedCPU;
//已用CPU时间 以时间片为单位
-
ProState ProcessState;
//进程状态
-
}PCB;
-
-
typedef
struct Node
-
{
-
ElemType data;
-
struct Node * Next;
-
}LNode,*LinkList;
-
-
-
-
#endif
ChainList.h
-
#ifndef _ChainList_h_
-
#define _ChainList_h_
-
-
#include "Data.h"
-
-
//功能:链表初始化
-
Status Init(LinkList *L);
-
-
//功能:赋值运算,将e2赋值给e1
-
void Assignment(ElemType *e1, ElemType e2);
-
-
//功能:获取第i个结点元素
-
Status GetElemt_L(LinkList L,int i,ElemType *e);
-
-
//功能:链表根据优先级插入元素
-
Status ListInsert_L(LinkList L,ElemType e);
-
-
//功能:链表删除头结点
-
Status ListDelete_L(LinkList L,ElemType *e);
-
-
-
#endif
ProPCB.h
-
#ifndef _ProPCB_h_
-
#define _ProPCB_h_
-
-
#include "ChainList.h"
-
-
//功能:将e插入链表Q
-
Status GetProcess(LinkList Q,ElemType e);
//上就绪队列
-
-
//功能:根据不同的优先级规则,返回优先数
-
int GetPriority(ElemType *e, PriorityRule PR);
//根据不同的规则PR 设置优先数
-
-
//功能:将链表Q的头结点数据放到e指向的内存,并删除
-
Status OutProsess(LinkList Q,ElemType *e);
//下就绪队列
-
-
//功能:CPU运行pcb指向的进程,并输出所有进行进程状态
-
Status CPURunPro(LinkList Q, PCB *pcb);
//CPU运行PCB
-
-
//功能:打印所有PCB信息
-
void PrintProQueue(LinkList Q, PCB *pcb);
//打印运行后PCB信息
-
-
//功能:当一个进程结束,打印进程信息
-
void PrintProResult(PCB *pcb);
-
-
#endif
实现
-
#include "ChainList.h"
-
-
extern
int CPUUsedTime;
-
-
//功能:链表初始化
-
Status Init(LinkList *L)
-
{
-
*L = (LinkList)
malloc(
sizeof(LNode));
-
(*L)->data.NeedRunningTime =
-1;
-
(*L)->Next =
NULL;
-
return OK;
-
}
-
-
//功能:赋值运算,将e2赋值给e1
-
void Assignment(ElemType *e1, ElemType e2)
-
{
-
e1->ArrivalTime = e2.ArrivalTime;
-
strcpy(e1->Name,e2.Name);
-
e1->Priority = e2.Priority;
-
e1->ProcessState = e2.ProcessState;
-
e1->FinishTime = e2.FinishTime;
-
e1->StartTime = e2.StartTime;
-
e1->NeedRunningTime = e2.NeedRunningTime;
-
e1->TimeUsedCPU = e2.TimeUsedCPU;
-
}
-
-
-
-
//链表中按照优先级:从大到小排序插入
-
Status ListInsert_L(LinkList L,ElemType e) //这样修改应该不对 p = *L出错
-
{
-
LinkList p = L->Next, pre = L, s;
-
while (p && e.Priority <= p->data.Priority)
-
{
-
pre = p;
-
p = p->Next;
-
}
-
s = (LinkList)
malloc(
sizeof(LNode));
-
Assignment(&s->data, e);
-
s->Next = pre->Next;
-
pre->Next = s;
-
return OK;
-
}
-
//链表中头部删除
-
Status ListDelete_L(LinkList L,ElemType *e)
-
{
-
LinkList p = L, q;
-
q = p->Next;
-
if(!q)
-
return ERROR;
-
p->Next = q->Next;
-
Assignment(e, q->data);
-
free(q);
-
return OK;
-
}
-
-
-
#include "ProPCB.h"
-
-
extern
int CPUUsedTime;
-
-
//功能:将e插入链表Q
-
Status GetProcess(LinkList Q,ElemType e)
-
{
-
return ListInsert_L(Q, e);
-
}
-
-
//功能:根据不同的优先级规则,返回优先数
-
int GetPriority(ElemType *e, PriorityRule PR)
-
{
-
if(PR == FCFS)
-
return Infinity - e->ArrivalTime;
-
else
if(PR == SPF)
-
return Infinity - e->NeedRunningTime;
-
else
-
printf(
"GetPriority Function ERROR!\n");
-
return ERROR;
-
}
-
-
//功能:将链表Q的头结点数据放到e指向的内存,并删除
-
Status OutProsess(LinkList Q,ElemType *e)
-
{
-
return ListDelete_L(Q ,e);
-
}
-
-
//上一次CPU运行时间增加1个时间片
-
Status CPURunPro(LinkList Q,PCB *pcb)
-
{
-
if(pcb->StartTime ==
-1)
-
pcb->StartTime = CPUUsedTime;
-
pcb->ProcessState = Running;
-
//PrintProQueue(Q, pcb);
-
pcb->TimeUsedCPU += TimeSlice;
-
-
return OK;
-
}
-
-
//功能:打印所有PCB信息
-
void PrintProQueue(LinkList Q, PCB *pcb)
-
{
-
LinkList p = Q->Next;
-
-
printf(
"进程名 优先数 到达时间 运行时间 已用CPU时间 完成时间 进程状态\n");
-
if(pcb)
-
printf(
" %4s %2d %4d %4d %3d(+1) %3d %4s \n",
-
pcb->Name,pcb->Priority,pcb->ArrivalTime,pcb->NeedRunningTime,
-
pcb->TimeUsedCPU, pcb->FinishTime,pcb->ProcessState == Ready ?
"就绪" :
"运行");
-
while (p)
-
{
-
printf(
" %4s %2d %4d %4d %3d %3d %4s \n",
-
p->data.Name,p->data.Priority,p->data.ArrivalTime,p->data.NeedRunningTime,
-
p->data.TimeUsedCPU,p->data.FinishTime, p->data.ProcessState == Ready ?
"就绪" :
"运行");
-
p = p->Next;
-
}
-
printf(
"-------------------------------------------------------------------------------\n");
-
}
-
-
//功能:当一个进程结束,打印进程信息
-
void PrintProResult(PCB *pcb)
-
{
-
printf(
"进程名 到达时刻 运行时间 开始时刻 完成时刻 周转时间 带权周转时间 进程状态\n");
-
if(pcb)
-
printf(
" %2s %3d %4d %4d %3d %4d %5.2lf %4s \n",
-
pcb->Name,pcb->ArrivalTime,pcb->NeedRunningTime,pcb->StartTime,pcb->FinishTime,
-
pcb->FinishTime-pcb->ArrivalTime,((pcb->FinishTime - pcb->ArrivalTime)*
1.0)/pcb->NeedRunningTime,
"完成");
-
-
printf(
"-------------------------------------------------------------------------------\n");
-
}
-
-
main:
-
#include "ProPCB.h"
-
-
/****************************
-
* 实验01: 非抢占式静态优先权 *
-
* ① 优先权始终保持不变 *
-
* ② 一旦进入CPU便运行到结束 *
-
* ③ FCFS只考虑到达时间进CPU *
-
* ④ SPF认为到达时间相同 *
-
****************************/
-
-
int CPUUsedTime =
0;
-
-
void InputData(LinkList * pPCBdata, PriorityRule PR)
-
{
-
ElemType e = {{
0},
-1,
-1,
-1,
-1,
-1,
0,Ready};
-
e.ArrivalTime =
0;
-
e.ProcessState = Ready;
-
e.TimeUsedCPU =
0;
-
strcpy(e.Name,
"A");
-
e.NeedRunningTime =
1;
-
e.Priority = GetPriority(&e, PR);
-
if(PR == SPF) e.ArrivalTime =
0;
-
GetProcess(*pPCBdata,e);
-
-
e.ArrivalTime =
1;
-
e.ProcessState = Ready;
-
e.TimeUsedCPU =
0;
-
strcpy(e.Name,
"B");
-
e.NeedRunningTime =
100;
-
e.Priority = GetPriority(&e, PR);
-
if(PR == SPF) e.ArrivalTime =
0;
-
GetProcess(*pPCBdata,e);
-
-
e.ArrivalTime =
2;
-
e.ProcessState = Ready;
-
e.TimeUsedCPU =
0;
-
strcpy(e.Name,
"C");
-
e.NeedRunningTime =
1;
-
e.Priority = GetPriority(&e, PR);
-
if(PR == SPF) e.ArrivalTime =
0;
-
GetProcess(*pPCBdata,e);
-
-
e.ArrivalTime =
3;
-
e.ProcessState = Ready;
-
e.TimeUsedCPU =
0;
-
strcpy(e.Name,
"D");
-
e.NeedRunningTime =
100;
-
e.Priority = GetPriority(&e, PR);
-
if(PR == SPF) e.ArrivalTime =
0;
-
GetProcess(*pPCBdata,e);
-
-
}
-
-
//void InputData1(LinkList * pPCBdata, PriorityRule PR)
-
//{
-
// ElemType e = {{0},-1,-1,-1,-1,-1,0,Ready};
-
// e.ArrivalTime = 0;
-
// e.ProcessState = Ready;
-
// e.TimeUsedCPU = 0;
-
// strcpy(e.Name,"A");
-
// e.NeedRunningTime = 4;
-
// e.Priority = GetPriority(&e, PR);
-
// if(PR == SPF) e.ArrivalTime = 0;
-
// GetProcess(*pPCBdata,e);
-
//
-
// e.ArrivalTime = 1;
-
// e.ProcessState = Ready;
-
// e.TimeUsedCPU = 0;
-
// strcpy(e.Name,"B");
-
// e.NeedRunningTime = 3;
-
// e.Priority = GetPriority(&e, PR);
-
// if(PR == SPF) e.ArrivalTime = 0;
-
// GetProcess(*pPCBdata,e);
-
//
-
// e.ArrivalTime = 2;
-
// e.ProcessState = Ready;
-
// e.TimeUsedCPU = 0;
-
// strcpy(e.Name,"C");
-
// e.NeedRunningTime = 5;
-
// e.Priority = GetPriority(&e, PR);
-
// if(PR == SPF) e.ArrivalTime = 0;
-
// GetProcess(*pPCBdata,e);
-
//
-
// e.ArrivalTime = 3;
-
// e.ProcessState = Ready;
-
// e.TimeUsedCPU = 0;
-
// strcpy(e.Name,"D");
-
// e.NeedRunningTime = 2;
-
// e.Priority = GetPriority(&e, PR);
-
// if(PR == SPF) e.ArrivalTime = 0;
-
// GetProcess(*pPCBdata,e);
-
//
-
// e.ArrivalTime = 4;
-
// e.ProcessState = Ready;
-
// e.TimeUsedCPU = 0;
-
// strcpy(e.Name,"E");
-
// e.NeedRunningTime = 4;
-
// e.Priority = GetPriority(&e, PR);
-
// if(PR == SPF) e.ArrivalTime = 0;
-
// GetProcess(*pPCBdata,e);
-
//}
-
-
-
int main(void)
-
{
-
LinkList PCBQueue;
//InitPCBdata里面存放PCB初始数据
-
ElemType e = {{
0},
-1,
-1,
-1,
-1,
-1,
0,Ready};
-
ElemType *pcb =
NULL;
-
PriorityRule PR;
-
PR = FCFS;
// SPF or FCFS
-
//*********** 初始化就绪队列 *************//
-
Init(&PCBQueue);
-
InputData(&PCBQueue, PR);
-
printf(
"初始数据如下:\n");
-
PrintProQueue(PCBQueue, pcb);
-
-
//*********** 进程根据优先级上CPU *************//
-
printf(
"\n进程运行信息如下:\n");
-
while (OutProsess(PCBQueue, &e))
-
{
-
//一次性运行完毕
-
while(e.TimeUsedCPU < e.NeedRunningTime)
//上完CPU的进程是否完毕
-
{
-
CPURunPro(PCBQueue, &e);
//上CPU
-
++CPUUsedTime;
//CPU时间增加
-
}
-
//*********** 当进程执行完毕时打印输出 *************//
-
e.FinishTime = CPUUsedTime;
-
PrintProResult(&e);
-
}
-
-
getchar();
-
return
0;
-
}
二、模拟银行家算法
介绍
data.h
-
#ifndef _Data_h_
-
#define _Data_h_
-
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <string.h>
-
-
#define ElemType PCB
-
#define Status int
-
#define true 1
-
#define false 0
-
#define OK 1
-
#define ERROR 0
-
#define RESOURCE_NUM 3
-
#define MAX_RESOURCE_A_NUM 10
-
#define MAX_RESOURCE_B_NUM 5
-
#define MAX_RESOURCE_C_NUM 7
-
#define NAME_MAXSIZE 20
-
#define PCB_Num 5
-
typedef
struct{
-
int MaxNum[RESOURCE_NUM];
//需要每项资源个数
-
int AllocationNum[RESOURCE_NUM];
//已占用每项资源个数
-
int NeedNum[RESOURCE_NUM];
//还需要的每项资源个数
-
}ResourceList;
-
-
typedef
struct
-
{
-
char Name[NAME_MAXSIZE];
//进程名
-
ResourceList resList;
//资源清单
-
}PCB;
-
-
typedef
struct Node
-
{
-
ElemType data;
-
struct Node * Next;
-
}LNode,*LinkList;
-
-
#endif
chainlist.h
-
#ifndef _ChainList_h_
-
#define _ChainList_h_
-
-
#include "Data.h"
-
-
Status Init(LinkList *L);
-
void Assignment(ElemType *e1, ElemType e2);
-
Status ListInsert_L(LinkList L,ElemType e);
-
-
#endif
实现
ProPCB.h
-
#ifndef _ProPCB_h_
-
#define _ProPCB_h_
-
-
#include "ChainList.h"
-
#include <string.h>
-
//上队列
-
Status GetProcess(LinkList Q,ElemType e);
-
//银行家算法
-
Status BankerAlgorithm(int *Allocation, int *Request,int i, int *Need, int *Available);
-
//安全性检测算法
-
Status SecurityCheck(int *Allocation,int *Need, int *Available);
-
//分配资源
-
Status AllocateResource(LinkList PCBdata , int pos , int *Request);
-
//获取资源矩阵
-
void GetMatrixData(LinkList PCBdata,int *Max,int *Allocation,int *Need,int *Available);
-
//打印进程资源信息
-
void PrintProQueue(LinkList L, int *A);
-
//得到指定PCB名的位置
-
void GetPos(LinkList L, char *name, int len, int *pos);
-
//对当前的请求进行预分配
-
void PreGrant(int* Allocation, int *Request,int pos,int *Need, int *Available);
-
//正式分配算法
-
void GrantSource(LinkList L, int *Request, int pos, int *Available);
-
-
#endif
chainlist.c
-
#include "ChainList.h"
-
extern
int CPUUsedTime;
-
Status Init(LinkList *L)
-
{
-
*L = (LinkList)
malloc(
sizeof(LNode));
-
strcpy((*L)->data.Name,
"");
-
(*L)->Next =
NULL;
-
return OK;
-
}
-
-
void Assignment(ElemType *e1, ElemType e2)
-
{
-
int i =
0;
-
strcpy(e1->Name,e2.Name);
-
for(i =
0; i < RESOURCE_NUM; ++i)
-
{
-
e1->resList.AllocationNum[i] = e2.resList.AllocationNum[i];
-
e1->resList.MaxNum[i] = e2.resList.MaxNum[i];
-
e1->resList.NeedNum[i] = e2.resList.NeedNum[i];
-
}
-
}
-
-
Status ListInsert_L(LinkList L,ElemType e) //这样修改应该不对 p = *L出错
-
{
-
LinkList p = L, s;
-
while (p->Next)
-
p = p->Next;
-
s = (LinkList)
malloc(
sizeof(LNode));
-
Assignment(&s->data, e);
-
s->Next = p->Next;
-
p->Next = s;
-
return OK;
-
}
-
ProPCB.c
-
#include "ProPCB.h"
-
-
Status GetProcess(LinkList Q,ElemType e)
-
{
-
return ListInsert_L(Q, e);
-
}
-
-
Status AllocateResource(LinkList PCBdata , int pos , int *Request)
-
{
-
int i =
1;
-
LNode *p = PCBdata->Next;
-
-
while (p && i < pos)
-
{
-
p = p->Next;
-
++i;
-
}
-
if(!p || i > pos)
-
return ERROR;
-
for (i =
0; i < RESOURCE_NUM; ++i)
-
{
-
p->data.resList.AllocationNum[i] += Request[i];
-
p->data.resList.NeedNum[i] -= Request[i];
-
}
-
return OK;
-
}
-
void GetMatrixData(LinkList PCBdata,int *Max,int *Allocation,int *Need,int *Available)
-
{
-
LNode *p;
-
int i, j, c = RESOURCE_NUM;
-
Available[
0] = Available[
1] = Available[
2] =
0;
-
for(p = PCBdata->Next, i =
0; p; p = p->Next, ++i)
-
{
-
for(j =
0; j < RESOURCE_NUM; ++j)
-
{
-
Max[i * c + j] = p->data.resList.MaxNum[j];
-
Allocation[i * c + j] = p->data.resList.AllocationNum[j];
-
Need[i * c + j] = p->data.resList.NeedNum[j];
-
}
-
Available[
0] += Allocation[i * c +
0];
-
Available[
1] += Allocation[i * c +
1];
-
Available[
2] += Allocation[i * c +
2];
-
}
-
Available[
0] = MAX_RESOURCE_A_NUM - Available[
0];
-
Available[
1] = MAX_RESOURCE_B_NUM - Available[
1];
-
Available[
2] = MAX_RESOURCE_C_NUM - Available[
2];
-
}
-
-
-
void PrintProQueue(LinkList L,int *available)
-
{
-
int i =
0;
-
L = L->Next;
-
printf(
" -------------------------------------------------------------\n");
-
printf(
"|进程名 | Max | Allocation | Need | Available |\n");
-
printf(
"| | A B C | A B C | A B C | A B C |\n");
-
while(L)
-
{
-
printf(
"| %s | %d %d %d | %d %d %d | %d %d %d | %d %d %d |\n",
-
L->data.Name, L->data.resList.MaxNum[
0], L->data.resList.MaxNum[
1], L->data.resList.MaxNum[
2],
-
L->data.resList.AllocationNum[
0],L->data.resList.AllocationNum[
1],L->data.resList.AllocationNum[
2],
-
L->data.resList.NeedNum[
0],L->data.resList.NeedNum[
1],L->data.resList.NeedNum[
2],
-
available[
0], available[
1], available[
2]);
-
L = L->Next;
-
}
-
printf(
" -------------------------------------------------------------\n");
-
-
}
-
-
//安全性检测算法
-
Status SecurityCheck(int *Allocation,int *Need, int *Available)
-
{
-
/ 以下补充
//
-
int work[RESOURCE_NUM];
-
int Finish[PCB_Num];
-
int k, i, j, t, f;
-
int flag;
-
-
//初始化工作向量和标记数组
-
memcpy(work, Available,
sizeof work);
-
memset(Finish,
0,
sizeof Finish);
-
-
//最多检测PCB_Num次
-
for(k =
0; k < PCB_Num; ++k){
-
flag =
0;
-
for(i =
0; i < PCB_Num; ++i){
-
//已经被访问
-
if(Finish[i]){
-
continue;
-
}
-
-
//检测是否所有资源都能被分配
-
for(j =
0; j < RESOURCE_NUM; ++j){
-
if(!(Need[i *
3 + j] <= work[j])){
-
break;
-
}
-
}
-
-
//可以满足,回收
-
if(j == RESOURCE_NUM){
-
for(t =
0; t < RESOURCE_NUM; ++t){
-
work[t] += Allocation[i *
3 + t];
-
}
-
Finish[i] =
1;
-
flag =
1;
-
break;
-
}
-
}
-
-
//为进行分配,跳出循环
-
if(!flag){
-
break;
-
}
-
}
-
-
for(f =
0; f < PCB_Num; ++f){
-
//只要有一个进程不满足,跳出循环
-
if(!Finish[f]){
-
return ERROR;
-
}
-
}
-
-
return OK;
-
}
-
-
//银行家算法
-
Status BankerAlgorithm(int* Allocation, int *Request,int pos,int *Need, int *Available)
-
{
-
/ 以下补充
//
-
int i;
-
//检查请求的是否大于需要的
-
for(i =
0; i < RESOURCE_NUM; ++i){
-
if(Request[i] > Need[pos*
3 + i]){
-
return ERROR;
-
}
-
}
-
-
//检查请求的是否大于可分配的
-
for(i =
0; i < RESOURCE_NUM; ++i){
-
if(Request[i] > Available[i]){
-
return ERROR;
-
}
-
}
-
-
//进行预分配
-
PreGrant(Allocation, Request, pos, Need, Available);
-
-
//进行安全性检测
-
if(!SecurityCheck(Allocation, Need, Available)){
-
return ERROR;
-
}
-
-
return OK;
-
}
-
-
//根据PCB的名字得到该PCB在链表中的位置
-
void GetPos(LinkList L, char *name, int len, int *pos)
-
{
-
LinkList p = L->Next;
-
char PcbName[NAME_MAXSIZE];
-
memcpy(PcbName, name, (len +
1) *
sizeof(
char));
-
(*pos) =
0;
-
-
while(p){
-
if(
strcmp(p->data.Name, PcbName)){
-
(*pos)++;
-
p = p->Next;
-
}
else {
-
break;
-
}
-
}
-
}
-
-
//预分配算法
-
void PreGrant(int* Allocation, int *Request,int pos,int *Need, int *Available){
-
int i;
-
//1. Need减去请求的
-
for(i =
0; i < RESOURCE_NUM; ++i){
-
Need[pos*
3 + i] -= Request[i];
-
}
-
-
//2. Available减去请求的
-
for(i =
0; i < RESOURCE_NUM; ++i){
-
Available[i] -= Request[i];
-
}
-
-
//3. Allocation加上请求的
-
for(i =
0; i < RESOURCE_NUM; ++i){
-
Allocation[pos*
3 + i] += Request[i];
-
}
-
}
-
-
/**
-
* 1.首先对请求资源的进程进行分配资源
-
* 2.如果给该进程分配资源之后,该进程所需的资源等于已经得到的资源,那么对其拥有的资源进行回收
-
*/
-
-
//正式分配算法,pos从0开始标记
-
void GrantSource(LinkList L, int *Request, int pos, int *Available){
-
LinkList p = L->Next;
-
int tag =
0;
-
int i;
-
int flag =
0;
-
-
if(tag < pos &&
NULL != p){
-
p = p->Next;
-
tag++;
-
}
-
-
if(p){
-
//已获得的加上请求的
-
for(i =
0; i < RESOURCE_NUM; ++i){
-
p->data.resList.AllocationNum[i] += Request[i];
-
}
-
-
//还需要的减去请求的
-
for(i =
0; i < RESOURCE_NUM; ++i){
-
p->data.resList.NeedNum[i] -= Request[i];
-
}
-
-
//可利用的减去请求的
-
for(i =
0; i < RESOURCE_NUM; ++i){
-
Available[i] -= Request[i];
-
}
-
-
//如果进行分配之后该进程最大所需资源数目等于已获得的资源数目,则对资源进行回收
-
flag =
0;
-
for(i =
0; i < RESOURCE_NUM; ++i){
-
if(p->data.resList.AllocationNum[i] != p->data.resList.MaxNum[i]){
-
flag =
1;
-
break;
-
}
-
}
-
-
if(!flag){
-
for(i =
0; i < RESOURCE_NUM; ++i){
-
Available[i] += p->data.resList.AllocationNum[i];
-
}
-
}
-
}
-
}
main
-
#include "ProPCB.h"
-
-
void InputData(LinkList * pPCBdata)
-
{
-
ElemType e = {{
0},{{
0},{
0},{
0}}};
-
strcpy(e.Name,
"P0");
-
e.resList.MaxNum[
0] =
7; e.resList.MaxNum[
1] =
5; e.resList.MaxNum[
2] =
3;
-
e.resList.AllocationNum[
0] =
0;
-
e.resList.AllocationNum[
1] =
1;
-
e.resList.AllocationNum[
2] =
0;
-
e.resList.NeedNum[
0] =
7; e.resList.NeedNum[
1] =
4; e.resList.NeedNum[
2] =
3;
-
GetProcess(*pPCBdata,e);
-
-
strcpy(e.Name,
"P1");
-
e.resList.MaxNum[
0] =
3; e.resList.MaxNum[
1] =
2; e.resList.MaxNum[
2] =
2;
-
e.resList.AllocationNum[
0] =
2;
-
e.resList.AllocationNum[
1] =
0;
-
e.resList.AllocationNum[
2] =
0;
-
e.resList.NeedNum[
0] =
1; e.resList.NeedNum[
1] =
2; e.resList.NeedNum[
2] =
2;
-
GetProcess(*pPCBdata,e);
-
-
strcpy(e.Name,
"P2");
-
e.resList.MaxNum[
0] =
9; e.resList.MaxNum[
1] =
0; e.resList.MaxNum[
2] =
2;
-
e.resList.AllocationNum[
0] =
3;
-
e.resList.AllocationNum[
1] =
0;
-
e.resList.AllocationNum[
2] =
2;
-
e.resList.NeedNum[
0] =
6; e.resList.NeedNum[
1] =
0; e.resList.NeedNum[
2] =
0;
-
GetProcess(*pPCBdata,e);
-
-
strcpy(e.Name,
"P3");
-
e.resList.MaxNum[
0] =
2; e.resList.MaxNum[
1] =
2; e.resList.MaxNum[
2] =
2;
-
e.resList.AllocationNum[
0] =
2;
-
e.resList.AllocationNum[
1] =
1;
-
e.resList.AllocationNum[
2] =
1;
-
e.resList.NeedNum[
0] =
0; e.resList.NeedNum[
1] =
1; e.resList.NeedNum[
2] =
1;
-
GetProcess(*pPCBdata,e);
-
-
strcpy(e.Name,
"P4");
-
e.resList.MaxNum[
0] =
4; e.resList.MaxNum[
1] =
3; e.resList.MaxNum[
2] =
3;
-
e.resList.AllocationNum[
0] =
0;
-
e.resList.AllocationNum[
1] =
0;
-
e.resList.AllocationNum[
2] =
2;
-
e.resList.NeedNum[
0] =
4; e.resList.NeedNum[
1] =
3; e.resList.NeedNum[
2] =
1;
-
GetProcess(*pPCBdata,e);
-
}
-
int main(void)
-
{
-
LinkList PCBdata;
//PCBdata里面存放原始数据
-
ElemType e = {{
0},{{
0},{
0},{
0}}};
-
-
char PcbName[NAME_MAXSIZE], chioce;
-
int Max[PCB_Num][RESOURCE_NUM] = {
0}, Allocation[PCB_Num][RESOURCE_NUM] = {
0};
-
int Need[PCB_Num][RESOURCE_NUM] = {
0}, Available[RESOURCE_NUM] = {
0};
-
int Request[RESOURCE_NUM] = {
0}, pos =
0;
-
LNode *p =
NULL;
-
int i;
-
-
/ 以下补充
//
-
-
//初始化就绪队列
-
Init(&PCBdata);
-
-
//数据输入
-
InputData(&PCBdata);
-
-
while(
1){
-
//获取所有PCB中的资源信息
-
GetMatrixData(PCBdata, *Max, *Allocation, *Need, Available);
-
-
//打印当前系统的状态
-
PrintProQueue(PCBdata, Available);
-
-
//接受请求
-
printf(
"请输入申请资源的进程名,资源A,资源B,资源C申请量(空格隔开):");
-
scanf(
"%s", PcbName);
-
for(i =
0; i < RESOURCE_NUM; ++i){
-
scanf(
"%d", &Request[i]);
-
}
-
-
//获取相应的PCB在链表中的位置
-
GetPos(PCBdata, PcbName,
strlen(PcbName), &pos);
-
-
//跑银行家算法,根据返回值的状态判断是否安全,
-
//如果安全,进行正式分配,否则仅仅打印不安全信息
-
if(BankerAlgorithm(*Allocation, Request, pos, *Need, Available)){
-
//正式分配资源
-
GrantSource(PCBdata, Request, pos, Available);
-
-
//分配完成后,打印资源的信息
-
GetMatrixData(PCBdata, *Max, *Allocation, *Need, Available);
-
PrintProQueue(PCBdata, Available);
-
printf(
"请安任意键继续. . . ");
-
getchar();
-
getchar();
-
}
else {
-
printf(
"不安全,不可分配!\n");
-
}
-
}
-
-
return
0;
-
}
三、模拟固定分区分配
介绍
data.h
-
#ifndef _Data_h_
-
#define _Data_h_
-
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <string.h>
-
#define LIST_INIT_SIZE 10
-
#define LISTINCREMENT 2
-
#define true 1
-
#define false 0
-
#define PCBType PCB
-
#define Status int
-
#define OK 1
-
#define ERROR 0
-
#define NAME_MAXSIZE 20
-
#define PCB_Num 5
-
#define LIST_INITSIZE 10
-
#define PartiType PartitionInfo
-
#define TotalMemory 512 //KB
-
-
-
typedef
enum
-
{
-
Unallocated, Allocated
-
}DistributState, PartitionSt;
-
-
typedef
enum
-
{
-
FirstPriority, BestAdapt
-
}AllocatStrategy;
-
-
-
typedef
struct
-
{
-
char Name[NAME_MAXSIZE];
//进程名
-
int MemorySize;
//内存的大小
-
int StartAddress;
//内存起始地址
-
DistributState DistbutSt;
//分配状态
-
}PCB;
-
-
typedef
struct Node
-
{
-
PCBType data;
-
struct Node * Next;
-
}LNode, *LinkList, *PCBList;
//
-
-
typedef
struct {
-
//分区号用数组下标代替
-
int PartitionSize;
-
int PartStartAddr;
-
char Name[NAME_MAXSIZE];
//若为空,则分区空闲
-
}PartitionInfo;
-
-
typedef
struct
-
{
-
PartiType *elem;
-
int listsize;
//表容量
-
int length;
//元素个数
-
}SqList, PartTable;
//分区表
-
-
#endif
list.h
-
#ifndef _List_h_
-
#define _List_h_
-
-
#include "Data.h"
-
-
//******* 链表 *******//
-
Status InitLinkList(LinkList *L);
-
void PCBAssign(PCBType *e1, PCBType e2);
-
Status GetElemt_L(LinkList L,int i,PCBType *e);
-
Status ListInsert_L(LinkList L,PCBType e);
-
Status ListDelete_L(LinkList L,int i,PCBType *e);
-
-
//****** 动态顺序表 ******//
-
void PartiAssign(PartiType *e1, PartiType e2);
-
Status InitList_Sq(SqList *L);
-
Status ListInsert_Sq(SqList *L,int i,PartiType e);
-
Status ListDelete_Sq(SqList *L,int i,PartiType *e);
-
-
#endif
-
#ifndef _MemoryManage_h_
-
#define _MemoryManage_h_
-
-
#include "List.h"
-
-
//***** PCB链表操作 *****//
-
Status InsertProcess(LinkList Q,PCBType e);
-
Status DeleteProsess(LinkList Q,int i,PCBType *e);
-
//***** 分区表操作 *****//
-
Status InsertTable(SqList *L, int i, PartiType e);
-
Status DeleteTable(SqList *L, int i, PartiType *e);
-
int SelectPart(PCB* pPCB, SqList *pPartTable);
-
int MallocMemory(PCB *pe, SqList *pPartTable, int pos);
-
void SearchSpace(PCBList PCBdata, SqList partTable);
-
void FreeMemory(int pos, SqList *pPartTable);
-
void InitAllocation(PCBList PCBdata, PartTable partTable);
-
void PrintProQueue(LinkList L);
-
void PrintPartTable(PartTable L);
-
-
-
-
-
#endif
实现
list.c
-
#include "List.h"
-
-
Status InitLinkList(LinkList *L)
-
{
-
*L = (LinkList)
malloc(
sizeof(LNode));
-
strcpy((*L)->data.Name,
"");
-
(*L)->Next =
NULL;
-
return OK;
-
}
-
-
void PCBAssign(PCBType *e1, PCBType e2)
-
{
-
strcpy(e1->Name,e2.Name);
-
e1->DistbutSt = e2.DistbutSt;
-
e1->MemorySize = e2.MemorySize;
-
e1->StartAddress = e2.StartAddress;
-
}
-
-
Status GetElemt_L(LinkList L,int i,PCBType *e)
-
{
-
LinkList p = L->Next;
//指向第j个结点
-
int j =
1;
//从第一个开始往后找
-
while ( p && j < i )
//p不为空且j < i
-
{
-
p = p->Next;
-
++j;
-
}
//p为空,说明链表循环结束,也没有到第i个结点 j==i
-
if (!p || j > i)
//因为此处对i 没有做判断 如果 i==0 或 负数 条件成立
-
//对于 i == j == 1 的情况则不用循环正好 返回
-
{
-
return ERROR;
-
}
-
*e = p->data;
//通过寻址改变了 该地址内存中元素的值
-
return OK;
-
}
-
//链表中按照优先级:从大到小排序插入
-
Status ListInsert_L(LinkList L,PCBType e) //这样修改应该不对 p = *L出错
-
{
-
LinkList p = L, s;
-
while (p->Next)
-
p = p->Next;
-
s = (LinkList)
malloc(
sizeof(LNode));
-
PCBAssign(&s->data, e);
-
s->Next = p->Next;
-
p->Next = s;
-
return OK;
-
}
-
//链表中头部删除
-
Status ListDelete_L(LinkList L,int i,PCBType *e)
-
{
-
LinkList p = L, q;
-
int j =
0;
-
while (p->Next && j < i
-1)
-
{
-
p = p->Next; ++j;
-
}
-
if(!p->Next || j > i -
1)
-
return ERROR;
-
q = p->Next;
-
p->Next = q->Next;
-
PCBAssign(e, q->data);
-
free(q);
-
return OK;
-
}
-
-
// 初始化 ///
-
void PartiAssign(PartiType *e1, PartiType e2)
-
{
-
e1->PartitionSize = e2.PartitionSize;
-
e1->PartStartAddr = e2.PartStartAddr;
-
strcpy(e1->Name, e2.Name);
-
}
-
-
Status InitList_Sq(SqList *L)
-
{
-
//构造一个空的线性表L
-
L->elem = (PartiType *)
malloc((LIST_INIT_SIZE)*
sizeof(PartiType));
-
if(!L->elem)
return ERROR;
//存储分配失败
-
L->length =
0;
//空表长度为0
-
L->listsize = LIST_INIT_SIZE;
//初始存储的容量
-
return OK;
-
}
-
-
//在顺序线性表L中第i个位置之前插入新的元素e
-
Status ListInsert_Sq(SqList *L,int i,PartiType e)
-
{
-
//在顺序线性表L中第i个位置之前插入新的元素e
-
//i的合法值为1 <= i <= ListLength_Sq(L)+1
-
PartiType *q, *p, *newbase;
-
-
if(i <
1 || i > L->length +
1 )
return ERROR;
//i值不合法
-
if(L->length >= L->listsize){
//当前存储空间已满,增加分配
-
newbase = (PartiType *)
realloc(L->elem
-
,(L->listsize + LISTINCREMENT)*
sizeof(PartiType));
-
if(!newbase)
return ERROR;
//存储分配失败
-
L->elem = newbase;
//新基址
-
L->listsize += LISTINCREMENT;
//增加存储容量
-
}
-
q = &(L->elem[i -
1]);
//q为插入位置
-
for(p = &(L->elem[L->length
-1]);p >= q; --p)
-
PartiAssign((p+
1),*p);
//插入位置及之后的元素右移
-
PartiAssign(q ,e);
//插入e
-
L->length++;
-
return OK;
-
}
-
-
//在顺序线性表L中删除第i个元素,并用e返回其值
-
Status ListDelete_Sq(SqList *L,int i,PartiType *e)
-
{
-
//在顺序线性表L中删除第i个元素,并用e返回其值
-
//i的合法值为1 <= i <= ListLength_Sq(L)
-
PartiType *p,*q;
-
if((i <
1) || (i > L->length))
-
return ERROR;
//i值不合法
-
p = &(L->elem[i
-1]);
//p为被删除元素的位置
-
PartiAssign(e, *p);
//将被删除元素的值赋给e (待定)
-
q = L->elem + L->length
-1;
//移动到表尾元素的位置
-
for (++p;p<=q;++p)
-
PartiAssign((p
-1), *p);
//被删除元素之后的元素左移
-
L->length--;
-
return OK;
-
}
-
memoryManage.c
-
#include "MemoryManage.h"
-
-
//***** PCB链表操作 *****//
-
Status InsertProcess(LinkList Q,PCBType e)
-
{
-
return ListInsert_L(Q, e);
-
}
-
-
Status DeleteProsess(LinkList Q,int i,PCBType *e)
-
{
-
return ListDelete_L(Q ,i,e);
-
}
-
-
//***** 分区表操作 *****//
-
Status InsertTable(SqList *L, int i, PartiType e)
-
{
-
return ListInsert_Sq(L,i, e);
-
}
-
-
Status DeleteTable(SqList *L, int i, PartiType *e)
-
{
-
return ListDelete_Sq(L, i, e);
-
}
-
-
-
//返回第几个内存块,从1开始,若返回0,则代表错误
-
int SelectPart(PCB* pPCB, SqList *pPartTable)
-
{
-
int i,Start;
-
if(pPCB->MemorySize <=
16)
-
Start =
0;
-
else
if(pPCB->MemorySize <=
32)
-
Start =
1;
-
else
if(pPCB->MemorySize <=
64)
-
Start =
2;
-
else
if(pPCB->MemorySize <=
128)
-
Start =
3;
-
else
if(pPCB->MemorySize <=
256)
-
Start =
4;
-
else
-
{
-
printf(
"内存过大,无法装入!\n");
-
return ERROR;
-
}
-
-
for (i = Start; i < pPartTable->length; ++i)
-
if(!
strcmp(pPartTable->elem[i].Name,
""))
-
return i +
1;
-
return ERROR;
-
}
-
-
//i传递的是下标
-
int MallocMemory(PCB *pe, SqList *pPartTable,int i)
-
{
-
/// 以下需要补充 /
-
pe->DistbutSt = Allocated;
-
pe->StartAddress = pPartTable->elem[i].PartStartAddr;
-
strcpy(pPartTable->elem[i].Name, pe->Name);
-
-
return OK;
-
}
-
-
/**
-
* PCBdata:表示PCB链
-
* partTable:分区表
-
* 将每一个PCB取出,查找是否有合适的分区可以分配给他,如果有分配,如果没有不分配
-
*/
-
void InitAllocation(PCBList PCBdata, PartTable partTable)
-
{
-
/// 以下需要补充 /
-
PCBList L = PCBdata->Next;
-
int pos;
-
-
while(L){
-
pos = SelectPart(&L->data, &partTable);
-
if(pos ==
0) {
-
printf(
"无法为%s进程分配空间!!!\n", L->data.Name);
-
}
else {
-
L->data.DistbutSt = Allocated;
-
L->data.StartAddress = partTable.elem[pos
-1].PartStartAddr;
-
strcpy(partTable.elem[pos
-1].Name, L->data.Name);
-
}
-
L = L->Next;
-
}
-
//SearchSpace(PCBdata, partTable);
-
}
-
-
void FreeMemory(int pos, SqList *pPartTable)
-
{
-
/// 以下需要补充 /
-
strcpy(pPartTable->elem[pos].Name,
"");
-
}
-
-
-
void SearchSpace(PCBList PCBdata, SqList partTable)
-
{
-
int pos;
-
LNode *p;
-
p = PCBdata->Next;
-
while (p)
-
{
-
if(p->data.DistbutSt == Unallocated)
-
{
-
pos = SelectPart(&(p->data), &partTable);
//从1开始
-
if(pos)
-
{
-
MallocMemory(&(p->data), &partTable, pos -
1);
-
break;
-
}
-
}
-
p = p->Next;
-
}
-
-
}
-
-
void PrintProQueue(LinkList L)
-
{
-
int i =
0;
-
L = L->Next;
-
printf(
" ----------------------------------------\n");
-
printf(
"|进程名 | 起始位置 | 申请大小 | 是否分配 |\n");
-
while(L)
-
{
-
printf(
"| %s | %4d | %4d | %4s |\n",
-
L->data.Name, L->data.StartAddress, L->data.MemorySize, L->data.DistbutSt == Allocated?
"是" :
"否");
-
L = L->Next;
-
}
-
printf(
" ----------------------------------------\n");
-
}
-
-
void PrintPartTable(PartTable L)
-
{
-
int i =
0, j =
0;
-
printf(
" ----------------------------------------\n");
-
printf(
"|分区号 | 起始位置 | 分区大小 | 是否分配 |\n");
-
for (i =
0; i < L.length; ++i)
-
printf(
"| %2d | %4d | %4d | %4s |\n",
-
i +
1 , L.elem[i].PartStartAddr, L.elem[i].PartitionSize ,
strcmp(L.elem[i].Name,
"") ? L.elem[i].Name :
"否");
-
printf(
" ----------------------------------------\n");
-
}
main
-
#include "MemoryManage.h"
-
-
/*实验06 固定分区分配
-
* 分配策略:
-
* ①离队首最近,能够装入该分区的进程;
-
* ②搜索能够装入该分区最大的进程。
-
*/
-
-
void InputPCBData(PCBList * pPCBdata)
-
{
-
PCBType e = {{
0},
0,
0, Unallocated};
-
strcpy(e.Name,
"P1");
-
e.MemorySize =
16;
-
InsertProcess(*pPCBdata,e);
-
-
strcpy(e.Name,
"P2");
-
e.MemorySize =
32;
-
InsertProcess(*pPCBdata,e);
-
-
strcpy(e.Name,
"P3");
-
e.MemorySize =
48;
-
InsertProcess(*pPCBdata,e);
-
-
strcpy(e.Name,
"P4");
-
e.MemorySize =
96;
-
InsertProcess(*pPCBdata,e);
-
-
strcpy(e.Name,
"P5");
-
e.MemorySize =
100;
-
InsertProcess(*pPCBdata,e);
-
}
-
-
void SetFixedZone(PartTable * pPartdata)
-
{
-
PartiType se = {
0,
0, Unallocated };
-
se.PartStartAddr =
16;
-
se.PartitionSize =
16;
-
InsertTable(pPartdata,
1, se);
-
-
se.PartStartAddr =
32;
-
se.PartitionSize =
32;
-
InsertTable(pPartdata,
2, se);
-
-
se.PartStartAddr =
64;
-
se.PartitionSize =
64;
-
InsertTable(pPartdata,
3, se);
-
-
se.PartStartAddr =
128;
-
se.PartitionSize =
128;
-
InsertTable(pPartdata,
4, se);
-
-
se.PartStartAddr =
256;
-
se.PartitionSize =
256;
-
InsertTable(pPartdata,
5, se);
-
-
}
-
//0 - 15Kb 操作系统占用 总大小512KB
-
int main(void)
-
{
-
PCBList PCBdata;
//PCBdata里面存放原始PCB数据
-
PartTable partTable;
//分区表
-
char PcbName[NAME_MAXSIZE] = {
0}, choice;
-
PCBType PCBe = {{
0},
0,
0, Unallocated};
-
PartiType Parte = {
0,
0};
-
PCBType tmp;
-
PCBType *pcb =
NULL;
-
LNode *p;
-
PCBList pl =
NULL;
-
int tpos =
0;
-
int startAddress;
-
-
int i, size, pos, j;
-
-
InitList_Sq(&partTable);
-
SetFixedZone(&partTable);
-
InitLinkList(&PCBdata);
-
InputPCBData(&PCBdata);
-
InitAllocation(PCBdata, partTable);
-
-
PrintProQueue(PCBdata);
-
PrintPartTable(partTable);
-
-
while(
true)
-
{
-
system(
"cls");
-
PrintProQueue(PCBdata);
-
PrintPartTable(partTable);
-
printf(
" ================================================\n");
-
printf(
"| 1.结 束 进 程 |\n");
-
printf(
"| 2.添 加 进 程 |\n");
-
printf(
"| 3.退 出 系 统 |\n");
-
printf(
" ================================================\n");
-
printf(
"请选择:");
-
fflush(
stdin);
-
scanf(
"%d",&choice);
-
-
//printf("haha");
-
switch (choice)
-
{
-
/// 以下需要补充 /
-
case
1:
-
printf(
"要结束的进程名:");
-
scanf(
"%s", PcbName);
-
//找到指定进程的位置,
-
pl = PCBdata->Next;
-
startAddress =
-1;
-
tpos =
0;
-
-
while(pl){
-
tpos++;
-
if(!
strcmp(pl->data.Name, PcbName) && pl->data.DistbutSt == Allocated){
-
startAddress = pl->data.StartAddress;
-
break;
-
}
-
pl = pl->Next;
-
}
-
-
if(startAddress ==
-1){
-
printf(
"进程不存在!!!\n");
-
break;
-
}
-
-
//删除进程
-
DeleteProsess(PCBdata, tpos, &tmp);
-
-
//根据起始地址找到要回收的分区
-
for(j =
0; j < partTable.length; ++j){
-
if(partTable.elem[j].PartStartAddr == startAddress){
-
tpos = j;
-
break;
-
}
-
}
-
-
//回收内存
-
FreeMemory(tpos, &partTable);
-
-
//重新检查是否可以为其他进程分配
-
SearchSpace(PCBdata, partTable);
-
break;
-
case
2:
-
printf(
"请输入添加的进程名和所占分区的大小:");
-
scanf(
"%s %d", PcbName, &size);
-
-
strcpy(PCBe.Name, PcbName);
-
PCBe.MemorySize = size;
-
PCBe.DistbutSt = Unallocated;
-
PCBe.StartAddress =
0;
-
InsertProcess(PCBdata, PCBe);
-
SearchSpace(PCBdata, partTable);
-
break;
-
case
3:
-
exit(
0);
-
break;
-
}
-
PrintProQueue(PCBdata);
-
PrintPartTable(partTable);
-
system(
"pause");
-
}
-
-
return
0;
-
}
四、模拟基本分页存储
介绍
data.h
-
#ifndef _Data_h_
-
#define _Data_h_
-
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <string.h>
-
#include <math.h>
-
-
#define LIST_INIT_SIZE 10
-
#define LISTINCREMENT 2
-
#define true 1
-
#define false 0
-
#define PCBType PCB
-
#define Status int
-
#define OK 1
-
#define ERROR 0
-
#define NAME_MAXSIZE 20
-
#define PCB_Num 5
-
#define LIST_INITSIZE 10
-
#define PartiType PartitionInfo
-
#define BlockNumType PageData //分页信息
-
#define TotalMemory 512 //KB
-
#define PageSize 16 //通常为1 ~ 8KB //进程申请内存的大小[16, 256]KB 256 / 8 = 32页
-
-
-
typedef
enum
-
{
-
Unallocated, Allocated
-
}DistributState, PartitionSt;
-
-
typedef
struct {
-
//分区号用数组下标代替
-
int PartStartAddr;
-
char Name[NAME_MAXSIZE];
//若为空,则分区空闲
-
}PartitionInfo;
-
-
typedef
struct
-
{
-
PartitionInfo *elem;
-
int listsize;
//表容量
-
int length;
//元素个数
-
}SqList_f, PartTable;
//分区使用说明表
-
-
-
typedef
struct {
-
int BlockNum;
//块号
-
DistributState DistbutSt;
//分配状态
-
}PageData;
-
-
-
typedef
struct
-
{
-
PageData *elem;
-
int listsize;
-
int length;
-
}SqList_y, PageTable;
//页表
-
-
-
typedef
struct
-
{
-
char Name[NAME_MAXSIZE];
//进程名
-
int MemorySize;
//内存的大小
-
PageTable *pPagetable;
//页表指针
-
}PCB;
-
-
typedef
struct Node
-
{
-
PCBType data;
-
struct Node * Next;
-
}LNode, *LinkList, *PCBList;
-
-
-
#endif
list.h
-
#ifndef _List_h_
-
#define _List_h_
-
-
#include "Data.h"
-
-
//******* 链表 *******//
-
Status InitLinkList(LinkList *L);
-
void PCBAssign(PCBType *e1, PCBType e2);
-
Status GetElemt_L(LinkList L,int i,PCBType *e);
-
Status ListInsert_L(LinkList L,PCBType e);
-
Status ListDelete_L(LinkList L,int i,PCBType *e);
-
-
//****** 分区使用说明表 ******//
-
void PartiAssign_f(PartiType *e1, PartiType e2);
-
Status InitList_f(SqList_f *L);
-
Status ListInsert_f(SqList_f *L,int i,PartiType e);
-
Status ListDelete_f(SqList_f *L,int i,PartiType *e);
-
-
-
//****** 页表 ******//
-
void PartiAssign_y(BlockNumType *e1, BlockNumType e2);
-
Status InitList_y(SqList_y **L);
-
Status ListInsert_y(SqList_y *L,int i,BlockNumType e);
-
Status ListDelete_y(SqList_y *L,int i,BlockNumType *e);
-
-
#endif
memorymanage.h
-
#ifndef _MemoryManage_h_
-
#define _MemoryManage_h_
-
-
#include "List.h"
-
-
//***** PCB 链 表 操 作 *****//
-
Status InsertProcess(LinkList Q,PCBType e);
-
Status DeleteProsess(LinkList Q,int i,PCBType *e);
-
//***** 分 区 表 操 作 *****//
-
//插入分区表元素
-
Status InsertTable_f(SqList_f *L, int i, PartiType e);
-
//删除分区表元素
-
Status DeleteTable_f(SqList_f *L, int i, PartiType *e);
-
-
-
//****** 页 表 操 作 ******//
-
//插入页表元素
-
Status InsertTable_y(SqList_y *L, int i, BlockNumType e);
-
//删除页表元素
-
Status DeleteTable_y(SqList_y *L, int i, BlockNumType *e);
-
Status LoadPages(PageTable *L, int size);
-
-
Status MallocMemory(PCB *pe, SqList_f *pPartTable, int *arr);
-
Status SelectPart(PCB* pPCB, SqList_f *pPartTable,int *arr);
-
void SearchSpace(PCBList PCBdata, SqList_f *partTable);
-
void FreeMemory(int *arr, int len, SqList_f *pPartTable);
-
void InitAllocation(PCBList PCBdata, PartTable *partTable);
-
void PrintProQueue(LinkList L);
-
void PrintPartTable(PartTable L);
-
-
-
-
-
#endif
实现
-
#include "List.h"
-
-
-
//******* 链表 *******//
-
Status InitLinkList(LinkList *L)
-
{
-
*L = (LinkList)
malloc(
sizeof(LNode));
-
strcpy((*L)->data.Name,
"");
-
(*L)->Next =
NULL;
-
return OK;
-
}
-
-
void PCBAssign(PCBType *e1, PCBType e2)
-
{
-
strcpy(e1->Name,e2.Name);
-
e1->MemorySize = e2.MemorySize;
-
e1->pPagetable = e2.pPagetable;
-
}
-
-
Status GetElemt_L(LinkList L,int i,PCBType *e)
-
{
-
LinkList p = L->Next;
//指向第j个结点
-
int j =
1;
//从第一个开始往后找
-
while ( p && j < i )
//p不为空且j < i
-
{
-
p = p->Next;
-
++j;
-
}
//p为空,说明链表循环结束,也没有到第i个结点 j==i
-
if (!p || j > i)
//因为此处对i 没有做判断 如果 i==0 或 负数 条件成立
-
//对于 i == j == 1 的情况则不用循环正好 返回
-
{
-
return ERROR;
-
}
-
*e = p->data;
//通过寻址改变了 该地址内存中元素的值
-
return OK;
-
}
-
//链表中按照优先级:从大到小排序插入
-
Status ListInsert_L(LinkList L,PCBType e) //这样修改应该不对 p = *L出错
-
{
-
LinkList p = L, s;
-
while (p->Next)
-
p = p->Next;
-
s = (LinkList)
malloc(
sizeof(LNode));
-
PCBAssign(&s->data, e);
-
s->Next = p->Next;
-
p->Next = s;
-
return OK;
-
}
-
-
Status ListDelete_L(LinkList L,int i,PCBType *e)
-
{
-
LinkList p = L, q;
-
int j =
0;
-
while (p->Next && j < i
-1)
-
{
-
p = p->Next; ++j;
-
}
-
if(!p->Next || j > i -
1)
-
return ERROR;
-
q = p->Next;
-
p->Next = q->Next;
-
PCBAssign(e, q->data);
-
free(q);
-
return OK;
-
}
-
-
//****** 分区使用说明表 ******//
-
void PartiAssign_f(PartiType *e1, PartiType e2)
-
{
-
e1->PartStartAddr = e2.PartStartAddr;
-
strcpy(e1->Name, e2.Name);
-
}
-
-
Status InitList_f(SqList_f *L)
-
{
-
//构造一个空的线性表L
-
L->elem = (PartiType *)
malloc((LIST_INIT_SIZE)*
sizeof(PartiType));
-
if(!L->elem)
return ERROR;
//存储分配失败
-
L->length =
0;
//空表长度为0
-
L->listsize = LIST_INIT_SIZE;
//初始存储的容量
-
return OK;
-
}
-
-
//在顺序线性表L中第i个位置之前插入新的元素e
-
Status ListInsert_f(SqList_f *L,int i,PartiType e)
-
{
-
//在顺序线性表L中第i个位置之前插入新的元素e
-
//i的合法值为1 <= i <= ListLength_Sq(L)+1
-
PartiType *q, *p, *newbase;
-
-
if(i <
1 || i > L->length +
1 )
return ERROR;
//i值不合法
-
if(L->length >= L->listsize){
//当前存储空间已满,增加分配
-
newbase = (PartiType *)
realloc(L->elem
-
,(L->listsize + LISTINCREMENT)*
sizeof(PartiType));
-
if(!newbase)
return ERROR;
//存储分配失败
-
L->elem = newbase;
//新基址
-
L->listsize += LISTINCREMENT;
//增加存储容量
-
}
-
q = &(L->elem[i -
1]);
//q为插入位置
-
for(p = &(L->elem[L->length
-1]);p >= q; --p)
-
PartiAssign_f((p+
1),*p);
//插入位置及之后的元素右移
-
PartiAssign_f(q ,e);
//插入e
-
L->length++;
-
return OK;
-
}
-
-
//在顺序线性表L中删除第i个元素,并用e返回其值
-
Status ListDelete_f(SqList_f *L,int i,PartiType *e)
-
{
-
//在顺序线性表L中删除第i个元素,并用e返回其值
-
//i的合法值为1 <= i <= ListLength_Sq(L)
-
PartiType *p,*q;
-
if((i <
1) || (i > L->length))
-
return ERROR;
//i值不合法
-
p = &(L->elem[i
-1]);
//p为被删除元素的位置
-
PartiAssign_f(e, *p);
//将被删除元素的值赋给e (待定)
-
q = L->elem + L->length
-1;
//移动到表尾元素的位置
-
for (++p;p<=q;++p)
-
PartiAssign_f((p
-1), *p);
//被删除元素之后的元素左移
-
L->length--;
-
return OK;
-
}
-
-
-
//****** 页表 ******//
-
-
void PartiAssign_y(BlockNumType *e1, BlockNumType e2)
-
{
-
(*e1).BlockNum = e2.BlockNum;
-
(*e1).DistbutSt = e2.DistbutSt;
-
}
-
-
Status InitList_y(SqList_y **L)
-
{
-
//构造一个空的线性表L
-
(*L) = (PageTable *)
malloc(
sizeof(PageTable));
//不可缺少
-
(*L)->elem = (BlockNumType *)
malloc((LIST_INIT_SIZE)*
sizeof(BlockNumType));
-
if(!(*L)->elem)
return ERROR;
//存储分配失败
-
(*L)->length =
0;
//空表长度为0
-
(*L)->listsize = LIST_INIT_SIZE;
//初始存储的容量
-
return OK;
-
}
-
-
//在顺序线性表L中第i个位置之前插入新的元素e
-
Status ListInsert_y(SqList_y *L,int i,BlockNumType e)
-
{
-
//在顺序线性表L中第i个位置之前插入新的元素e
-
//i的合法值为1 <= i <= ListLength_Sq(L)+1
-
BlockNumType *q, *p, *newbase;
-
-
if(i <
1 || i > L->length +
1 )
return ERROR;
//i值不合法
-
if(L->length >= L->listsize){
//当前存储空间已满,增加分配
-
newbase = (BlockNumType *)
realloc(L->elem
-
,(L->listsize + LISTINCREMENT)*
sizeof(BlockNumType));
-
if(!newbase)
return ERROR;
//存储分配失败
-
L->elem = newbase;
//新基址
-
L->listsize += LISTINCREMENT;
//增加存储容量
-
}
-
q = &(L->elem[i -
1]);
//q为插入位置
-
for(p = &(L->elem[L->length
-1]);p >= q; --p)
-
PartiAssign_y((p+
1),*p);
//插入位置及之后的元素右移
-
PartiAssign_y(q ,e);
//插入e
-
L->length++;
-
return OK;
-
}
-
-
//在顺序线性表L中删除第i个元素,并用e返回其值
-
Status ListDelete_y(SqList_y *L,int i,BlockNumType *e)
-
{
-
//在顺序线性表L中删除第i个元素,并用e返回其值
-
//i的合法值为1 <= i <= ListLength_Sq(L)
-
BlockNumType *p,*q;
-
if((i <
1) || (i > L->length))
-
return ERROR;
//i值不合法
-
p = &(L->elem[i
-1]);
//p为被删除元素的位置
-
PartiAssign_y(e, *p);
//将被删除元素的值赋给e (待定)
-
q = L->elem + L->length
-1;
//移动到表尾元素的位置
-
for (++p;p<=q;++p)
-
PartiAssign_y((p
-1), *p);
//被删除元素之后的元素左移
-
L->length--;
-
return OK;
-
}
memorymanage.c
-
-
#include "MemoryManage.h"
-
-
//***** PCB链表操作 *****//
-
Status InsertProcess(LinkList Q,PCBType e)
-
{
-
return ListInsert_L(Q, e);
-
}
-
-
Status DeleteProsess(LinkList Q,int i,PCBType *e)
-
{
-
return ListDelete_L(Q ,i,e);
-
}
-
-
//***** 分区表操作 *****//
-
Status InsertTable_f(SqList_f *L, int i, PartiType e)
-
{
-
return ListInsert_f(L,i, e);
-
}
-
-
Status DeleteTable_f(SqList_f *L, int i, PartiType *e)
-
{
-
return ListDelete_f(L, i, e);
-
}
-
-
//***** 页表操作 *****//
-
Status InsertTable_y(SqList_y *L, int i, BlockNumType e)
-
{
-
return ListInsert_y(L,i, e);
-
}
-
-
Status DeleteTable_y(SqList_y *L, int i, BlockNumType *e)
-
{
-
return ListDelete_y(L, i, e);
-
}
-
-
Status LoadPages(PageTable *L, int size)
-
{
-
int i, pageNum =
ceil( size *
1.0 / PageSize) ;
-
PageData e = {
-1, Unallocated};
-
for (i =
0; i < pageNum; i++)
-
{
-
if(!InsertTable_y(L, L->length +
1, e))
-
return ERROR;
-
}
-
return OK;;
-
}
-
-
//若返回0,则代表错误
-
Status SelectPart(PCB* pPCB, SqList_f *pPartTable,int *arr)
-
{
-
/ 以下补充 /
-
int i =
0, j =
0;
-
-
while(i < pPCB->pPagetable->length && j < pPartTable->length){
-
if(pPCB->pPagetable->elem[i].DistbutSt == Unallocated){
-
if(!
strcmp(pPartTable->elem[j].Name,
"")){
-
arr[i] = j;
-
++i;
-
++j;
-
}
else {
-
++j;
-
}
-
}
else {
-
++i;
-
}
-
}
-
-
if(i == pPCB->pPagetable->length){
-
return OK;
-
}
-
return ERROR;
-
}
-
-
Status MallocMemory(PCB *pe, SqList_f *pPartTable, int *arr)
-
{
-
int i, pageNum ;
-
-
以下补充 /
-
for(i =
0; i < pe->pPagetable->length; ++i){
-
if(pe->pPagetable->elem[i].DistbutSt == Unallocated){
-
pe->pPagetable->elem[i].BlockNum = arr[i];
-
pe->pPagetable->elem[i].DistbutSt = Allocated;
-
-
strcpy(pPartTable->elem[arr[i]].Name, pe->Name);
-
}
-
}
-
-
return ERROR;
-
}
-
-
void InitAllocation(PCBList PCBdata, PartTable *pPartTable)
-
{
-
LNode *p;
-
int pos, arr[
20] = {
0};
-
p = PCBdata->Next;
-
while (p)
-
{
-
if(p->data.pPagetable->elem[
0].DistbutSt == Unallocated)
-
{
-
if(SelectPart(&(p->data), pPartTable, arr))
-
{
-
MallocMemory(&(p->data), pPartTable, arr);
-
}
-
}
-
p = p->Next;
-
}
-
}
-
-
//该释放进程只在结束进程时用到,因此不用管进程信息
-
void FreeMemory(int *arr, int len, SqList_f *pPartTable)
-
{
-
int i;
-
以下补充 /
-
for(i =
0; i < len; ++i){
-
strcpy(pPartTable->elem[arr[i]].Name,
"");
-
}
-
}
-
-
void SearchSpace(PCBList PCBdata, SqList_f *partTable)
-
{
-
int pos, arr[
20] = {
0};
-
LNode *p;
-
p = PCBdata->Next;
-
while (p)
-
{
-
if(p->data.pPagetable->elem[
0].DistbutSt == Unallocated)
-
{
-
if(SelectPart(&(p->data), partTable, arr))
-
{
-
MallocMemory(&(p->data), partTable, arr);
-
}
-
}
-
p = p->Next;
-
}
-
-
}
-
-
void PrintProQueue(LinkList L)
-
{
-
int i =
0;
-
-
L = L->Next;
-
-
while(L)
-
{
-
printf(
" -----------------------------\n");
-
printf(
"|进程名 | 申请大小 |\n");
-
printf(
"| %s | %4d |\n", L->data.Name, L->data.MemorySize);
-
-
printf(
"%s页表信息如下:\n| 页号 | 块号 | 是否分配 |\n", L->data.Name);
-
for (i =
0; i < L->data.pPagetable->length; i++)
-
printf(
"| %4d | %4d | %4s |\n", i , L->data.pPagetable->elem[i].BlockNum,
-
L->data.pPagetable->elem[i].DistbutSt == Allocated?
"是" :
"否");
-
L = L->Next;
-
}
-
printf(
" ----------------------------------------\n");
-
}
-
-
void PrintPartTable(PartTable L)
-
{
-
int i =
0, j =
0;
-
printf(
" ----------------------------------------\n");
-
printf(
"|分区号 | 起始位置 | 分区大小 | 是否分配 |\n");
-
for (i =
0; i < L.length; ++i)
-
printf(
"| %2d | %4d | %4d | %4s |\n",
-
i , L.elem[i].PartStartAddr, PageSize ,
strcmp(L.elem[i].Name,
"") ? L.elem[i].Name :
"否");
-
printf(
" ----------------------------------------\n");
-
}
main
-
#include "MemoryManage.h"
-
-
/* 实验08 基本分页 */
-
-
void InputPCBData(PCBList * pPCBdata)
-
{
-
PCBType e = {{
0},
0,
NULL};
-
-
strcpy(e.Name,
"P1");
-
e.MemorySize =
16;
-
InitList_y(&(e.pPagetable));
-
LoadPages(e.pPagetable, e.MemorySize);
-
InsertProcess(*pPCBdata,e);
-
-
strcpy(e.Name,
"P2");
-
e.MemorySize =
32;
-
InitList_y(&(e.pPagetable));
-
LoadPages(e.pPagetable, e.MemorySize);
-
InsertProcess(*pPCBdata,e);
-
-
strcpy(e.Name,
"P3");
-
e.MemorySize =
48;
-
InitList_y(&(e.pPagetable));
-
LoadPages(e.pPagetable, e.MemorySize);
-
InsertProcess(*pPCBdata,e);
-
-
strcpy(e.Name,
"P4");
-
e.MemorySize =
96;
-
InitList_y(&(e.pPagetable));
-
LoadPages(e.pPagetable, e.MemorySize);
-
InsertProcess(*pPCBdata,e);
-
-
strcpy(e.Name,
"P5");
-
e.MemorySize =
100;
-
InitList_y(&(e.pPagetable));
-
LoadPages(e.pPagetable, e.MemorySize);
-
InsertProcess(*pPCBdata,e);
-
}
-
-
void SettingPage(PartTable * pPartdata)
-
{
-
PartiType se = {
0, {
0}};
-
int Num = (
512 -
16) / PageSize , i;
-
for (i =
0; i < Num; ++i)
-
{
-
se.PartStartAddr =
16 + i * PageSize;
-
InsertTable_f(pPartdata, i +
1, se);
-
}
-
}
-
//0 - 15Kb 操作系统占用 总大小512KB
-
int main(void)
-
{
-
PCBList PCBdata;
//PCBdata里面存放原始PCB数据
-
PartTable partTable;
//分区表
-
char PcbName[NAME_MAXSIZE] = {
0}, choice;
-
PCBType PCBe = {{
0},
0,
NULL};
-
PartiType Parte = {
0,
0};
-
PCBType *pcb =
NULL;
-
LNode *p;
-
-
int i, size, pos, arr[
20] = {
0}, k =
0;
-
-
InitList_f(&partTable);
-
SettingPage(&partTable);
-
InitLinkList(&PCBdata);
-
InputPCBData(&PCBdata);
-
-
InitAllocation(PCBdata, &partTable);
-
-
PrintProQueue(PCBdata);
-
PrintPartTable(partTable);
-
-
while(
true)
-
{
-
system(
"cls");
-
PrintProQueue(PCBdata);
-
PrintPartTable(partTable);
-
printf(
" ================================================\n");
-
printf(
"| 1.结 束 进 程 |\n");
-
printf(
"| 2.添 加 进 程 |\n");
-
printf(
"| 3.退 出 系 统 |\n");
-
printf(
" ================================================\n");
-
printf(
"请选择:");
-
fflush(
stdin);
-
scanf(
"%c",&choice);
-
-
switch (choice)
-
{
-
case
'1':
-
printf(
"要结束的进程名:");
-
scanf(
"%s",PcbName);
-
for (p = PCBdata->Next, i =
1; p &&
strcmp(PcbName, p->data.Name); i++, p = p->Next);
-
if(!p)
-
{
-
printf(
"进程名输入错误!\n");
-
break;
-
}
-
DeleteProsess(PCBdata, i, &PCBe);
-
k =
0;
-
for(i =
0; i < partTable.length; i++)
-
{
-
if(!
strcmp(PcbName, partTable.elem[i].Name))
-
{
-
arr[k++] = i;
-
}
-
}
-
FreeMemory(arr, k, &partTable);
-
-
SearchSpace(PCBdata, &partTable);
-
break;
-
case
'2':
-
printf(
"请输入添加的进程名,进程所占内存大小:");
-
scanf(
"%s%d",PcbName , &size);
-
strcpy(PCBe.Name, PcbName);
-
PCBe.MemorySize = size;
-
InitList_y(&(PCBe.pPagetable));
-
LoadPages(PCBe.pPagetable, PCBe.MemorySize);
-
if(SelectPart(&(PCBe), &partTable, arr))
-
MallocMemory(&(PCBe), &partTable, arr);
-
InsertProcess(PCBdata, PCBe);
-
break;
-
case
'3':
-
return
0;
-
-
default:
-
printf(
"选择项输入错误,重新选择!\n");
-
break;
-
}
-
PrintProQueue(PCBdata);
-
PrintPartTable(partTable);
-
system(
"pause");
-
}
-
-
return
0;
-
}
五、模拟动态分区分配
介绍
list.h
-
#ifndef _List_h_
-
#define _List_h_
-
-
#include "Data.h"
-
-
//******* 链表 *******//
-
Status InitLinkList(LinkList *L);
-
void PCBAssign(PCBType *e1, PCBType e2);
-
Status GetElemt_L(LinkList L,int i,PCBType *e);
-
Status ListInsert_L(LinkList L,PCBType e);
-
Status ListDelete_L(LinkList L,int i,PCBType *e);
-
-
//****** 动态顺序表 ******//
-
void PartiAssign(PartiType *e1, PartiType e2);
-
Status InitList_Sq(SqList *L);
-
Status ListInsert_Sq(SqList *L,int i,PartiType e);
-
Status ListDelete_Sq(SqList *L,int i,PartiType *e);
-
-
#endif
MemoryManage.h
-
#ifndef _MemoryManage_h_
-
#define _MemoryManage_h_
-
-
#include "List.h"
-
-
//***** PCB链表操作 *****//
-
Status InsertProcess(LinkList Q,PCBType e);
-
Status DeleteProsess(LinkList Q,int i,PCBType *e);
-
//***** 分区表操作 *****//
-
Status InsertTable(SqList *L, int i, PartiType e);
-
Status DeleteTable(SqList *L, int i, PartiType *e);
-
int SelectPart(PCB* pPCB, SqList *pPartTable, AllocatStrategy AS);
-
int MallocMemory(PCB *pe, SqList *pPartTable,int i);
-
void SearchSpace(PCBList PCBdata, SqList *partTable, AllocatStrategy AS);
-
void FreeMemory(int pos, SqList *pPartTable);
-
void InitAllocation(PCBList PCBdata, PartTable *partTable, AllocatStrategy AS);
-
void PrintProQueue(LinkList L);
-
void PrintPartTable(PartTable L);
-
-
-
-
-
#endif
实现
list.c
-
#include "List.h"
-
-
Status InitLinkList(LinkList *L)
-
{
-
*L = (LinkList)
malloc(
sizeof(LNode));
-
strcpy((*L)->data.Name,
"");
-
(*L)->Next =
NULL;
-
return OK;
-
}
-
-
void PCBAssign(PCBType *e1, PCBType e2)
-
{
-
strcpy(e1->Name,e2.Name);
-
e1->DistbutSt = e2.DistbutSt;
-
e1->MemorySize = e2.MemorySize;
-
e1->StartAddress = e2.StartAddress;
-
}
-
-
Status GetElemt_L(LinkList L,int i,PCBType *e)
-
{
-
LinkList p = L->Next;
//指向第j个结点
-
int j =
1;
//从第一个开始往后找
-
while ( p && j < i )
//p不为空且j < i
-
{
-
p = p->Next;
-
++j;
-
}
//p为空,说明链表循环结束,也没有到第i个结点 j==i
-
if (!p || j > i)
//因为此处对i 没有做判断 如果 i==0 或 负数 条件成立
-
//对于 i == j == 1 的情况则不用循环正好 返回
-
{
-
return ERROR;
-
}
-
*e = p->data;
//通过寻址改变了 该地址内存中元素的值
-
return OK;
-
}
-
//链表中按照优先级:从大到小排序插入
-
Status ListInsert_L(LinkList L,PCBType e) //这样修改应该不对 p = *L出错
-
{
-
LinkList p = L, s;
-
while (p->Next)
-
p = p->Next;
-
s = (LinkList)
malloc(
sizeof(LNode));
-
PCBAssign(&s->data, e);
-
s->Next = p->Next;
-
p->Next = s;
-
return OK;
-
}
-
//链表中头部删除
-
Status ListDelete_L(LinkList L,int i,PCBType *e)
-
{
-
LinkList p = L, q;
-
int j =
0;
-
while (p->Next && j < i
-1)
-
{
-
p = p->Next; ++j;
-
}
-
if(!p->Next || j > i -
1)
-
return ERROR;
-
q = p->Next;
-
p->Next = q->Next;
-
PCBAssign(e, q->data);
-
free(q);
-
return OK;
-
}
-
-
// 初始化 ///
-
void PartiAssign(PartiType *e1, PartiType e2)
-
{
-
e1->PartitionSize = e2.PartitionSize;
-
e1->PartStartAddr = e2.PartStartAddr;
-
strcpy(e1->Name, e2.Name);
-
}
-
-
Status InitList_Sq(SqList *L)
-
{
-
//构造一个空的线性表L
-
L->elem = (PartiType *)
malloc((LIST_INIT_SIZE)*
sizeof(PartiType));
-
if(!L->elem)
return ERROR;
//存储分配失败
-
L->length =
0;
//空表长度为0
-
L->listsize = LIST_INIT_SIZE;
//初始存储的容量
-
return OK;
-
}
-
-
//在顺序线性表L中第i个位置之前插入新的元素e
-
Status ListInsert_Sq(SqList *L,int i,PartiType e)
-
{
-
//在顺序线性表L中第i个位置之前插入新的元素e
-
//i的合法值为1 <= i <= ListLength_Sq(L)+1
-
PartiType *q, *p, *newbase;
-
-
if(i <
1 || i > L->length +
1 )
return ERROR;
//i值不合法
-
if(L->length >= L->listsize){
//当前存储空间已满,增加分配
-
newbase = (PartiType *)
realloc(L->elem
-
,(L->listsize + LISTINCREMENT)*
sizeof(PartiType));
-
if(!newbase)
return ERROR;
//存储分配失败
-
L->elem = newbase;
//新基址
-
L->listsize += LISTINCREMENT;
//增加存储容量
-
}
-
q = &(L->elem[i -
1]);
//q为插入位置
-
for(p = &(L->elem[L->length
-1]);p >= q; --p)
-
PartiAssign((p+
1),*p);
//插入位置及之后的元素右移
-
PartiAssign(q ,e);
//插入e
-
L->length++;
-
return OK;
-
}
-
-
//在顺序线性表L中删除第i个元素,并用e返回其值
-
Status ListDelete_Sq(SqList *L,int i,PartiType *e)
-
{
-
//在顺序线性表L中删除第i个元素,并用e返回其值
-
//i的合法值为1 <= i <= ListLength_Sq(L)
-
PartiType *p,*q;
-
if((i <
1) || (i > L->length))
-
return ERROR;
//i值不合法
-
p = &(L->elem[i
-1]);
//p为被删除元素的位置
-
PartiAssign(e, *p);
//将被删除元素的值赋给e (待定)
-
q = L->elem + L->length
-1;
//移动到表尾元素的位置
-
for (++p;p<=q;++p)
-
PartiAssign((p
-1), *p);
//被删除元素之后的元素左移
-
L->length--;
-
return OK;
-
}
-
-
#include "MemoryManage.h"
-
extern
int CF_i;
-
-
//***** PCB链表操作 *****//
-
Status InsertProcess(LinkList Q,PCBType e)
-
{
-
return ListInsert_L(Q, e);
-
}
-
-
Status DeleteProsess(LinkList Q,
int i,PCBType *e)
-
{
-
return ListDelete_L(Q ,i,e);
-
}
-
-
//***** 分区表操作 *****//
-
Status InsertTable(SqList *L,
int i, PartiType e)
-
{
-
return ListInsert_Sq(L,i, e);
-
}
-
-
Status DeleteTable(SqList *L,
int i, PartiType *e)
-
{
-
return ListDelete_Sq(L, i, e);
-
}
-
-
-
//返回第几个内存块,从1开始,若返回0,则代表错误
-
int SelectPart(PCB* pPCB, SqList *pPartTable,AllocatStrategy
AS)
-
{
-
int i;
-
int BestArr[
20] = {
0}, k =
0, min =
500, min_i =
-1;
-
-
if(
AS == FirstPriority)
-
{
-
for (i =
0; i < pPartTable->length; ++i)
-
if(!strcmp(pPartTable->elem[i].Name,
"") && pPartTable->elem[i].PartitionSize >= pPCB->MemorySize)
-
return i +
1;
-
}
else
if(
AS == BestAdapt)
-
{
-
以下补充 /
-
for(i =
0; i < pPartTable->length; ++i){
-
if(!strcmp(pPartTable->elem[i].Name,
"") && pPartTable->elem[i].PartitionSize >= pPCB->MemorySize)
-
if(pPartTable->elem[i].PartitionSize - pPCB->MemorySize < min){
-
min = pPartTable->elem[i].PartitionSize - pPCB->MemorySize;
-
min_i = i;
-
}
-
}
-
return min_i+
1;
-
}
else
if(
AS == CycleFirst)
-
{
-
int flag =
0;
-
以下补充 /
-
for(i = CF_i; i < pPartTable->length; i = (i+
1)%(pPartTable->length)){
-
if(!strcmp(pPartTable->elem[i].Name,
"") && pPartTable->elem[i].PartitionSize >= pPCB->MemorySize){
-
CF_i = (i+
1)%pPartTable->length;
-
return i +
1;
-
}
-
-
if(flag && i == CF_i){
-
break;
-
}
-
-
if(i == CF_i){
-
flag =
1;
-
}
-
}
-
-
return
0;
-
}
else
-
{
-
printf(
"算法选择有误!\n");
-
}
-
return
ERROR;
-
}
-
-
//通过SelectPart查找是否存在可以分配的分区,在main函数中进行调用本方法进行内存的分配
-
int MallocMemory(PCB *pe, SqList *pPartTable,
int i)
-
{
-
PartiType se = {
0,
0, {
0}};
-
以下补充 /
-
-
//修改PCB
-
pe->DistbutSt = Allocated;
-
pe->StartAddress = pPartTable->elem[i].PartStartAddr;
-
-
if(pPartTable->elem[i].PartitionSize == pe->MemorySize){
-
strcpy(pPartTable->elem[i].Name, pe->Name);
-
}
else {
-
//修改分区使用说明表
-
strcpy(pPartTable->elem[i].Name,
"");
-
pPartTable->elem[i].PartitionSize -= pe->MemorySize;
-
pPartTable->elem[i].PartStartAddr += pe->MemorySize;
-
-
//新建一个表目, 并插入分区表使用说明表
-
strcpy(se.Name, pe->Name);
-
se.PartitionSize = pe->MemorySize;
-
se.PartStartAddr = pe->StartAddress;
-
InsertTable(pPartTable, i+
1, se);
-
}
-
-
return OK;
-
}
-
-
void InitAllocation(PCBList PCBdata, PartTable *pPartTable,AllocatStrategy
AS)
-
{
-
LNode *p;
-
int pos;
-
p = PCBdata->Next;
-
while (p)
-
{
-
if(p->data.DistbutSt == Unallocated)
-
{
-
pos = SelectPart(&(p->data), pPartTable,
AS);
//从1开始
-
if(pos)
-
{
-
MallocMemory( &(p->data), pPartTable, pos -
1);
-
}
-
}
-
p = p->Next;
-
}
-
}
-
-
//回收指定位置的内存空间
-
void FreeMemory(
int pos, SqList *pPartTable)
//没考虑 pos为0情况,没考虑删除后修改起始地址情况
-
{
-
PartiType se = {
0,
0, {
0}};
-
int flag =
0;
-
以下补充 /
-
-
-
if(pos != pPartTable->length
-1){
-
//为后一块分配
-
if(!strcmp(pPartTable->elem[pos+
1].Name,
"")){
-
strcpy(pPartTable->elem[pos].Name,
"");
-
pPartTable->elem[pos].PartitionSize += pPartTable->elem[pos+
1].PartitionSize;
-
-
strcpy(se.Name, pPartTable->elem[pos+
1].Name);
-
se.PartitionSize = pPartTable->elem[pos+
1].PartitionSize;
-
se.PartStartAddr = pPartTable->elem[pos+
1].PartStartAddr;
-
DeleteTable(pPartTable, pos+
1, &se);
-
flag =
1;
-
}
-
}
-
-
if(pos !=
0){
-
-
//为前一块分配
-
if(!strcmp(pPartTable->elem[pos
-1].Name,
"")){
-
strcpy(pPartTable->elem[pos
-1].Name,
"");
-
pPartTable->elem[pos
-1].PartitionSize += pPartTable->elem[pos].PartitionSize;
-
-
strcpy(se.Name, pPartTable->elem[pos
-1].Name);
-
se.PartitionSize = pPartTable->elem[pos
-1].PartitionSize;
-
se.PartStartAddr = pPartTable->elem[pos
-1].PartStartAddr;
-
DeleteTable(pPartTable, pos
-1, &se);
-
flag =
1;
-
}
-
}
-
-
if(!flag){
-
strcpy(pPartTable->elem[pos].Name,
"");
-
}
-
}
-
-
void SearchSpace(PCBList PCBdata, SqList *partTable, AllocatStrategy
AS)
-
{
-
int pos;
-
LNode *p;
-
p = PCBdata->Next;
-
while (p)
-
{
-
if(p->data.DistbutSt == Unallocated)
-
{
-
pos = SelectPart(&(p->data), partTable,
AS);
//从1开始
-
if(pos)
-
{
-
MallocMemory(&(p->data), partTable, pos -
1);
-
}
-
}
-
p = p->Next;
-
}
-
-
}
-
-
void PrintProQueue(LinkList L)
-
{
-
int i =
0;
-
L = L->Next;
-
printf(
" ----------------------------------------\n");
-
printf(
"|进程名 | 起始位置 | 申请大小 | 是否分配 |\n");
-
while(L)
-
{
-
printf(
"| %s | %4d | %4d | %4s |\n",
-
L->data.Name, L->data.StartAddress, L->data.MemorySize, L->data.DistbutSt == Allocated?
"是" :
"否");
-
L = L->Next;
-
}
-
printf(
" ----------------------------------------\n");
-
}
-
-
void PrintPartTable(PartTable L)
-
{
-
int i =
0, j =
0;
-
printf(
" ----------------------------------------\n");
-
printf(
"|分区号 | 起始位置 | 分区大小 | 是否分配 |\n");
-
for (i =
0; i < L.length; ++i)
-
printf(
"| %2d | %4d | %4d | %4s |\n",
-
i +
1 , L.elem[i].PartStartAddr, L.elem[i].PartitionSize , strcmp(L.elem[i].Name,
"") ? L.elem[i].Name :
"否");
-
printf(
" ----------------------------------------\n");
-
}
main
-
#include "MemoryManage.h"
-
-
/*实验06 动态分区分配
-
*/
-
-
int CF_i;
-
-
void InputPCBData(PCBList * pPCBdata)
-
{
-
PCBType e = {{
0},
0,
0, Unallocated};
-
strcpy(e.Name,
"P1");
-
e.MemorySize =
16;
-
InsertProcess(*pPCBdata,e);
-
-
strcpy(e.Name,
"P2");
-
e.MemorySize =
32;
-
InsertProcess(*pPCBdata,e);
-
-
strcpy(e.Name,
"P3");
-
e.MemorySize =
48;
-
InsertProcess(*pPCBdata,e);
-
-
strcpy(e.Name,
"P4");
-
e.MemorySize =
96;
-
InsertProcess(*pPCBdata,e);
-
-
strcpy(e.Name,
"P5");
-
e.MemorySize =
100;
-
InsertProcess(*pPCBdata,e);
-
}
-
-
void SetFixedZone(PartTable * pPartdata)
-
{
-
PartiType se = {
0,
0, {
0}};
-
se.PartStartAddr =
16;
-
se.PartitionSize =
512 -
16;
-
strcpy(se.Name,
"");
-
InsertTable(pPartdata,
1, se);
-
}
-
//0 - 15Kb 操作系统占用 总大小512KB
-
int main(void)
-
{
-
PCBList PCBdata;
//PCBdata里面存放原始PCB数据
-
PartTable partTable;
//分区表
-
char PcbName[NAME_MAXSIZE] = {
0}, choice;
-
PCBType PCBe = {{
0},
0,
0, Unallocated};
-
PartiType Parte = {
0,
0};
-
PCBType *pcb =
NULL;
-
LNode *p;
-
AllocatStrategy AS = CycleFirst;
//FirstPriority, BestAdapt, CycleFirst
-
//AllocatStrategy AS = BestAdapt;
-
int i, size, pos;
-
-
//分区表
-
InitList_Sq(&partTable);
-
SetFixedZone(&partTable);
-
-
//进程表
-
InitLinkList(&PCBdata);
-
InputPCBData(&PCBdata);
-
-
//初始化
-
InitAllocation(PCBdata, &partTable, AS);
-
CF_i =
0;
-
-
PrintProQueue(PCBdata);
-
PrintPartTable(partTable);
-
-
while(
true)
-
{
-
system(
"cls");
-
PrintProQueue(PCBdata);
-
PrintPartTable(partTable);
-
printf(
" ================================================\n");
-
printf(
"| 1.结 束 进 程 |\n");
-
printf(
"| 2.添 加 进 程 |\n");
-
printf(
"| 3.退 出 系 统 |\n");
-
printf(
" ================================================\n");
-
printf(
"请选择:");
-
fflush(
stdin);
-
scanf(
"%c",&choice);
-
-
switch (choice)
-
{
-
case
'1':
-
printf(
"要结束的进程名:");
-
scanf(
"%s",PcbName);
-
for (p = PCBdata->Next, i =
1; p &&
strcmp(PcbName, p->data.Name); i++, p = p->Next);
-
if(!p)
-
{
-
printf(
"进程名输入错误!\n");
-
break;
-
}
-
DeleteProsess(PCBdata, i, &PCBe);
-
for(i =
0; i < partTable.length; i++)
-
{
-
if(!
strcmp(PcbName, partTable.elem[i].Name))
-
{
-
FreeMemory(i ,&partTable);
-
break;
-
}
-
}
-
-
SearchSpace( PCBdata, &partTable, AS);
-
break;
-
case
'2':
-
printf(
"请输入添加的进程名,进程所占内存大小:");
-
scanf(
"%s%d",PcbName , &size);
-
PCBe.DistbutSt = Unallocated;
-
PCBe.StartAddress =
0;
-
strcpy(PCBe.Name, PcbName);
-
PCBe.MemorySize = size;
-
pos = SelectPart(&(PCBe), &partTable, AS);
//从1开始
-
if(pos)
-
MallocMemory(&(PCBe), &partTable, pos -
1);
-
InsertProcess(PCBdata, PCBe);
-
break;
-
case
'3':
-
return
0;
-
-
default:
-
printf(
"选择项输入错误,重新选择!\n");
-
break;
-
}
-
PrintProQueue(PCBdata);
-
PrintPartTable(partTable);
-
system(
"pause");
-
}
-
-
return
0;
-
}
转载:https://blog.csdn.net/hebtu666/article/details/115171870
查看评论