目录
- 实验目的 1
- 实验内容 1
1.处理机调度: 1
2.基本存储管理: 1
3.作业进程控制: 1 - 实验环境 2
- 系统分析与设计 2
1.JCB,PCB的链接组织方式 2
2.页表 2
3.位视图 2
4.银行家算法相关数据结构 2
1.作业高响应比调度 2
2.进程优先级调度 3
3.作业调入内存 4
只需要把该作业占据的位视图置0 6
5.进程创建 6
功能:把进程阻塞起来,插到阻塞队列 8
10.进程模拟运行s 9 - 当进程请求资源,调用银行家算法进行检测 15
- 当资源分配失败时,进程进入阻塞队列 16
操作系统 Windows 7/10
编程语言及工具 C, DevC++
配置文件 无
备注
4.系统分析与设计
(1)数据结构
1.JCB,PCB的链接组织方式
JCB有2条队列:后备队列和运行队列。
PCB有4条队列:空闲队列、就绪队列、运行队列、阻塞队列。
队列是单链表队列。
对JCB来说,2条队列是独立的,每个节点都是动态分配的。对PCB来说,所有节点都是系统已经分配好的,用一个数组来存储这些节点。
2.页表
页表是一个顺序表,大小为内存块数量,每个进程都拥有一项页表。顺序表的下标代表作业的页号,内容代表该页号对应的内存块号。
3.位视图
位视图是一个顺序表,大小为内存块数量/8,一位代表一个内存块。字节号i位号j代表编号为i*8+j的内存块。
#include "../inc/core.h"
#include "../inc/shell.h"
#include "../inc/common.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/****************************资源相关变量定义******************/
static int *Avaliable; //每种资源可用数量
static int **MaxNeed; //进程对资源的最大需求量
static int **Need; //进程对资源的需求量
static int **Allocation; //资源给进程的分配量
static int **Request; //对每种资源的申请量
static int *Free; //资源可使用量
static int *Finish; //进程完成标志
static PCB_Pointer *List; //存放非阻塞进程的临时数组,用于银行家算法
static int resourceCnt; //系统资源数
static int timePiece; //进程运行单位时间片
static int runtime; //系统开机到此刻是时间
/**************************************************************/
/****************************进程相关变量定义*******************/
//系统存放所有进程PCB的表
static PCB_Pointer PCBTable;
//就绪队列头指针
static PCB readyPCB;
static PCB_Pointer readyPCBHead;
//阻塞队列头指针
static PCB blockPCB;
static PCB_Pointer blockPCBHead;
//阻塞队列头指针
static PCB runPCB;
static PCB_Pointer runPCBHead;
//空白队列头指针
static PCB freePCB;
static PCB_Pointer freePCBHead;
static int runCnt; //运行进程数
static int readyCnt; //就绪进程数
static int blockCnt; //阻塞进程数
static int freeCnt; //空闲PCB数
static int allocationCnt; //已分配进程数
/**************************************************************/
/****************************作业相关变量定义*******************/
//位视图
static byte *bitMap;
//页表
static int **pageTable;
//空闲存块数量
static int freeBlockCnt;
//系统的JCB表
JCB_Pointer JCBTable;
//空闲JCB队列头
JCB freeJCB;
JCB *freeJCBHead;
//就绪JCB队列
JCB readyJCB;
JCB *readyJCBHead;
//正在使用的JCB队列头
JCB usedJCB;
JCB *usedJCBHead;
/**************************************************************/
/***********************系统相关静态函数声明****************/
static int configSystem(const char *file);
static void releaseSystem();
static void MaxRequest(const char *file, int max[]);
/**************************************************************/
/***********************作业相关静态函数声明****************/
static void dispatchJob();
static JCB_Pointer HRRF();
static void dispatchJCB(JCB *p_jcb);
/**************************************************************/
/***********************进程相关静态函数声明****************/
static void printProcess(PCB_Pointer head);
static void insertPCB(PCB_Pointer head, PCB_Pointer p_pcb);
static void insertJCB(JCB_Pointer head, JCB_Pointer p_pcb);
static void printBanker();
static int security(PCB_Pointer list[], int n);
static int banker(PCB_Pointer p, PCB_Pointer list[], int n);
static void printBanker(PCB_Pointer list[], int n);
static int getRunTime(const char *file);
/**************************************************************/
/***********************系统相关代码块**********************/
void incTime()
{
runtime++;
}
static int configSystem(const char *file)
{
int i=0,j=0;
char str[10];
FILE *fp = NULL;
fp=fopen(file,"r");
if(!fp){
printf("配置文件打开失败\n");
return 0;
}
puts("配置系统基本信息");
fgets(str,10,fp);
MAX_PROCESS_CNT = atoi(str);
printf("系统最大进程数量:%d\n",MAX_PROCESS_CNT);
fgets(str,10,fp);
MAX_PRIORITY = atoi(str);
printf("系统最大优先级:%d\n",MAX_PRIORITY);
fgets(str,10,fp);
MAX_RESOURCE_CNT = atoi(str);
printf("系统最大资源种类数量:%d\n",MAX_RESOURCE_CNT);
fgets(str,10,fp);
MAX_JCB_CNT = atoi(str);
printf("系统最大作业数量:%d\n",MAX_JCB_CNT);
printf("系统内存大小:%dB\n",MEMORY_SIZE);
fgets(str,10,fp);
MEMORY_BLOCK_SIZE = atoi(str);
printf("系统内存块大小:%dB\n",MEMORY_BLOCK_SIZE);
MEMORY_BLOCK_COUNT = MEMORY_SIZE/MEMORY_BLOCK_SIZE;
printf("系统内存块数量:%d\n",MEMORY_BLOCK_COUNT);
fgets(str,10,fp);
CMD_SIZE = atoi(str);
printf("系统指令大小:%dB\n",CMD_SIZE);
fgets(str,10,fp);
resourceCnt = atoi(str);
printf("系统资源种类数量:%d\n",resourceCnt);
Avaliable=(int *)malloc(sizeof(int)*MAX_RESOURCE_CNT);
for(i=0;i<resourceCnt;i++){
fgets(str,10,fp);
Avaliable[i]=atoi(str);
printf("%d号资源:%d\n",i,Avaliable[i]);
}
printf("\n");
MaxNeed=(int**)malloc(sizeof(int*)*MAX_PROCESS_CNT);
for(i=0;i<MAX_PROCESS_CNT;i++) {
MaxNeed[i]=(int*)malloc(sizeof(int)*MAX_RESOURCE_CNT);
}
Need=(int**)malloc(sizeof(int*)*MAX_PROCESS_CNT);
for(i=0;i<MAX_PROCESS_CNT;i++)
Need[i]=(int*)malloc(sizeof(int)*MAX_RESOURCE_CNT);
Allocation=(int**)malloc(sizeof(int*)*MAX_PROCESS_CNT);
for(i=0;i<MAX_PROCESS_CNT;i++) {
Allocation[i]=(int*)malloc(sizeof(int)*MAX_RESOURCE_CNT);
for(j=0;j<MAX_RESOURCE_CNT;j++) Allocation[i][j]=0;
}
Request=(int**)malloc(sizeof(int*)*MAX_PROCESS_CNT);
for(i=0;i<MAX_PROCESS_CNT;i++) {
Request[i]=(int*)malloc(sizeof(int)*MAX_RESOURCE_CNT);
for(j=0;j<MAX_RESOURCE_CNT;j++) Request[i][j]=0;
}
Free=(int *)malloc(sizeof(int)*MAX_RESOURCE_CNT);
Finish=(int *)malloc(sizeof(int)*MAX_RESOURCE_CNT);
List=(PCB_Pointer *)malloc(sizeof(PCB_Pointer)*MAX_PROCESS_CNT);
PCBTable=(PCB *)malloc(sizeof(PCB)*MAX_PROCESS_CNT);
bitMap=(byte *)malloc(sizeof(byte)*(MEMORY_BLOCK_COUNT/8+1));
JCBTable=(JCB *)malloc(sizeof(JCB)*MAX_JCB_CNT);
pageTable=(int**)malloc(sizeof(int*)*MAX_JCB_CNT);
for(i=0;i<MAX_JCB_CNT;i++){
pageTable[i]=(int*)malloc(sizeof(int)*MEMORY_BLOCK_COUNT);
}
fclose(fp);
return 1;
}
static void releaseSystem()
{
int i=0;
free(Avaliable);
for(i=0;i<MAX_PROCESS_CNT;i++) {
free(MaxNeed[i]);
free(Need[i]);
free(Allocation[i]);
free(Request[i]);
}
free(MaxNeed);
free(Need);
free(Allocation);
free(Request);
free(Free);
free(Finish);
free(List);
free(PCBTable);
free(bitMap);
free(JCBTable);
for(i=0;i<MAX_JCB_CNT;i++) {
free(pageTable[i]);
}
free(pageTable);
}
//统计文件有多少个req指令。
//把它们的资源数想加,得出他们的MAX
static void MaxRequest(const char *file, int max[])
{
char buf[32];
char *buff,*p,*s;
int len,a,b,i,resource=1;
FILE * fp;
fp=fopen(file,"r");
if(fp==NULL){
printf("无法打开程序文件,进程运行失败");
return ;
}
for(i=0;i<resourceCnt;i++) max[i]=0;
while(!feof(fp)){
buff=fgets(buf,32,fp);
if(feof(fp)) break;
if(strstr(buff,"req")!=NULL){
i=0;
s=strtok(buff," req" );
a=atoi(s);
max[i++]+=a;
while((p = strtok(NULL, " "))){
b=atoi(p);
max[i++]+=b;
}
}
}
}
/**
* 函数名:InitSystem
* 功能:初始化系统。包括初始化PCB,资源等
* 参数:无
* 返回值:无
*/
void InitSystem()
{
int i=0;
int res;
res=configSystem("etc/etc.txt");
if(res==0) return;
/************PCB初始化*************/
//初始化空闲队列
puts("初始化JCB空闲队列成功");
freePCBHead=&freePCB;
freePCBHead->next=&PCBTable[0];
freeCnt=MAX_PROCESS_CNT;
for(i=0;i<MAX_PROCESS_CNT-1;i++){
PCBTable[i].status=FREE;
PCBTable[i].priority=0;
PCBTable[i].next=&PCBTable[i+1];
}
PCBTable[i].status=FREE;
PCBTable[i].priority=0;
PCBTable[i].next=NULL;
//初始化就绪队列
puts("初始化JCB就绪队列成功");
readyCnt=0;
readyPCBHead=&readyPCB;
readyPCBHead->next=NULL;
//初始化运行队列
puts("初始化JCB运行队列成功");
runCnt=0;
runPCBHead=&runPCB;
runPCBHead->next=NULL;
//初始化阻塞队列
puts("初始化JCB阻塞队列成功");
blockCnt=0;
blockPCBHead=&blockPCB;
blockPCBHead->next=NULL;
//分配数量
allocationCnt=0;
/***********************************/
/************JCB初始化**************/
//初始化空闲JCB队列
puts("初始化JCB空闲队列成功");
freeJCBHead=&freeJCB;
freeJCBHead->next=&JCBTable[0];
freeCnt=MAX_JCB_CNT;
for(i=0;i<MAX_JCB_CNT-1;i++){
JCBTable[i].size=0;
JCBTable[i].next=&JCBTable[i+1];
}
JCBTable[i].size=0;
JCBTable[i].next=NULL;
//初始化就绪JCB队列
puts("初始化JCB阻塞队列成功");
readyJCBHead=&readyJCB;
//初始化正在使用JCB队列
puts("初始化JCB运行队列成功");
usedJCBHead=&usedJCB;
//初始化空闲时间块
freeBlockCnt=MEMORY_BLOCK_COUNT;
//初始化位视图
puts("初始化位视图成功");
for(i=0;i<=MEMORY_BLOCK_COUNT/8;i++) bitMap[i]=0;
/*************************************/
//默认时间片为1
timePiece=2;
runtime=0;
}
/**
* 函数名:StartSystem
* 功能:启动系统,运行进程
* 参数:无
* 返回值:无
*/
void StartSystem()
{
//创建一个主作业来完成系统初始化工作
puts("创建一个系统作业来完成系统进一步的初始化工作");
createJob(0,MAX_PRIORITY,"etc/init.txt");
puts("\n\n创建系统进程完毕,系统开始运行...\n");
//直到所有进程运行结束
while(allocationCnt>0){
//取出就绪队列优先级最高的PCB即队头放到运行队列中
printf("进程就绪队列:");
printProcess(readyPCBHead);
runPCBHead->next=readyPCBHead->next;
readyPCBHead->next=readyPCBHead->next->next;
runPCBHead->next->next=NULL;
runCnt++;
readyCnt--;
//执行程序
printf("切换进程%d\n",runPCBHead->next->pid);
runProcess(runPCBHead->next);
if(runPCBHead->next->kind==USER && runPCBHead->next->priority>0){
runPCBHead->next->priority--;
}
runCnt--;
switch (runPCBHead->next->status){
case READY: //若未运行结束,插入到就绪队列继续运行
insertPCB(readyPCBHead,runPCBHead->next);
readyCnt++;
break;
case FREE: //已经运行结束
printf("进程%d执行完毕,准备销毁进程...\n",runPCBHead->next->pid);
destroyProcess(runPCBHead->next);
break;
case BLOCK: //进入阻塞
blockProcess(runPCBHead->next);
break;
default: break;
}
}
puts("所有进程运行结束,释放系统所有资源\n");
releaseSystem();
}
/*****************************************************************/
/**********************作业相关代码块*****************************/
//从后背队列选择作业并调入内存
static void dispatchJob()
{
JCB_Pointer p=readyJCBHead->next;
float w;
printf("系统空余内存块数量:%d\n",freeBlockCnt);
if(p==NULL) {
puts("后背队列为空,无须调度");
}
printf("当前作业后备队列:\n");
puts("jid 块数量 响应比");
while(p){
w=1+(float)(runtime-p->reachTime)/p->runTime;
printf("%d %d %.2f\n",p->jid,(p->size-1)/MEMORY_BLOCK_SIZE+1,w);
p=p->next;
}
puts(" ");
p=HRRF();
if(p==NULL) puts("找不到内存可以容纳的作用");
while(p){
printf("调度作业%d\n",p->jid);
p->next=usedJCBHead->next;
usedJCBHead->next=p;
puts("准备调入内存...");
dispatchJCB(p);
puts("作业调入内存成功,准备创建进程...\n");
createProcess(p,p->jid,p->priority);
p=HRRF();
}
}
/**
* 函数名:HRRF
* 功能:作业调度,相应比有效。
从作业队列刷选出运行时间最短并且内存能够容纳的的作业,从队列中删除并返回。
* 参数:无
* 返回值:无
*/
static JCB_Pointer HRRF()
{
JCB_Pointer p=readyJCBHead, s=NULL;
float maxw=0; //无穷大
float w; //响应比
while(p->next != NULL){
w=1+(float)(runtime-p->next->reachTime)/p->next->runTime;
if((p->next->size-1)/MEMORY_BLOCK_SIZE<freeBlockCnt&&w>maxw){
maxw=w;
s=p;
}
p=p->next;
}
if(s!=NULL) {
p=s;
s=s->next;
p->next=p->next->next;
}
return s;
}
/**
* 函数名:dispatchJCB
* 功能:把作业调入内存
* 参数:JCB指针
* 返回值:无
*/
static void dispatchJCB(JCB *p_jcb)
{
int i=0, j=0, k=0;
int blockCnt=(p_jcb->size-1)/MEMORY_BLOCK_SIZE+1; //作业占据的内存块数量
int row=p_jcb-JCBTable;
int n=MEMORY_BLOCK_COUNT/8;
FILE * fp;
int size=0;
char ch;
byte buff[MEMORY_BLOCK_SIZE];
puts("\n当前内存使用情况(位视图)");
puts(" 0 1 2 3 4 5 6 7");
puts("----------------");
for(i=0;i<MEMORY_BLOCK_COUNT;i++){
j=i%8;
if(j==0){
printf("%d|",i/8);
}
printf("%d ",((bitMap[i/8]>>j)&0x01));
if(j==7) printf("\n");
}
printf("\n\n");
printf("找到空闲内存块:");
for(i=0;i<MEMORY_BLOCK_COUNT&&k<blockCnt;i++){
j=i%8;
if(((bitMap[i/8]>>j)&0x01)==0x00){
bitMap[i/8]|=(1<<j); //至1
pageTable[row][k++]=i;
printf("%d ",i);
}
}
puts("\n");
puts("把页块对应关系写入页表");
printf("\n作业%d的页表\n",p_jcb->jid);
puts("页 块");
for(i=0;i<blockCnt;i++) printf("%d -> %d\n",i,pageTable[row][i]);
freeBlockCnt-=blockCnt;
puts("\n把磁盘的执行文件拷贝到内存...");
fp=fopen(p_jcb->file,"r");
if(!fp) {
printf("作业调入内存失败\n");
return ;
}
i=j=size=0;
while(!feof(fp)){
fgets(buff,CMD_SIZE,fp);
if(feof(fp)) break;
for(i=strlen(buff)-1;i<CMD_SIZE;i++) buff[i]=' ';
buff[i]='\0';
// puts(buff);
DMAWrite(pageTable[row][j]*MEMORY_BLOCK_SIZE+size,buff,CMD_SIZE);
size+=CMD_SIZE;
if(size%MEMORY_BLOCK_SIZE==0){
size=0;
j++;
}
}
fclose(fp);
puts("拷贝成功");
}
/**
* 函数名:recycleJCB
* 功能:从内存回收作业
* 参数:JCB指针
* 返回值:无
*/
static void recycleJCB(JCB *p_jcb)
{
int i=0, j=0, k=0;
int blockCnt=(p_jcb->size-1)/MEMORY_BLOCK_SIZE+1; //作业占据的内存块数量
int row=p_jcb-JCBTable;
//在页表中寻找作业占据的内存块并释放
for(k=0;k<blockCnt;k++){
i=pageTable[row][k]/8;
j=pageTable[row][k]%8;
bitMap[i]&=~(1<<j); //至0
}
freeBlockCnt+=blockCnt;
}
/**
* 函数名:createJob
* 功能:创建一个作业
* 参数:作业id, 程序文件
* 返回值:无
*/
void createJob(int jid, int priority, const char *file)
{
JCB_Pointer p;
//从JCB空闲队列获取头PCB
p=freeJCBHead->next;
freeJCBHead->next=freeJCBHead->next->next;
p->jid=jid;
p->priority=priority;
p->reachTime=runtime;
p->runTime=getFileRowCnt(file);
p->size=p->runTime*CMD_SIZE;
strcpy(p->file,file);
printf("\n创建作业:\n");
printf("jid runtime reachtime size\n");
printf(" %d %d %d %d\n",p->jid, p->runTime,p->reachTime,p->size);
printf("作业需要内存块数量:%d\n系统空余内存块数量:%d\n",(p->size-1)/MEMORY_BLOCK_SIZE+1,freeBlockCnt);
//若内存充足则调入内存,形成进程
if((p->size-1)/MEMORY_BLOCK_SIZE<freeBlockCnt){
puts("内存充足,准备调入内存...");
p->next=usedJCBHead->next;
usedJCBHead->next=p;
dispatchJCB(p);
puts("作业调入内存成功,准备创建进程...\n");
createProcess(p,p->jid,priority);
}
//否则插入作业就绪队列
else{
printf("空闲块不足,进入作业后备队列\n\n");
p->next=readyJCBHead->next;
readyJCBHead->next=p;
}
}
/**************************************************************/
/**********************进程相关代码块***********************/
//打印进程队列
static void printProcess(PCB_Pointer head)
{
PCB_Pointer p=head->next;
while(p != NULL){
printf("%d ",p->pid);
p=p->next;
}
puts("\n");
}
//按优先级从高到低把PCB插入到PCB队列中
static void insertPCB(PCB_Pointer head, PCB_Pointer p_pcb)
{
PCB_Pointer p=head;
while(p->next!=NULL && p->next->priority>p_pcb->priority) p=p->next;
p_pcb->next=p->next;
p->next=p_pcb;
}
/**
* 函数名:security
* 功能:对进程序列进list行安全检测,若存在安全序列,则存放到list中
* 参数:进程序列, 大小
* 返回值:1=安全,0=不安全
*/
static int security(PCB_Pointer list[], int n)
{
int i=0,k=0;
int flag=1;
int row;
PCB_Pointer *securityList=(PCB_Pointer*)malloc(sizeof(PCB_Pointer)*n); //安全序列
//初始化
ArrayAssign(Free,Avaliable,resourceCnt);
ArrayInit(Finish,MAX_PROCESS_CNT,0);
//寻找安全序列
while(flag){
flag=0;
for(i=0;i<n;i++){
row=list[i]-PCBTable;
if(Finish[row]==0 && ArrayIsSmaller(Need[row],Free,resourceCnt)){
ArrayAdd(Free,Allocation[row],resourceCnt);
securityList[k++]=list[i];
Finish[row]=flag=1;
i=0;
}
}
}
i=0;
while(i<n&&Finish[list[i]-PCBTable]==1) list[i]=securityList[i++];
free(securityList);
return i<n?0:1;
}
//银行家算法
static int banker(PCB_Pointer p, PCB_Pointer list[], int n)
{
int i=0,res;
int row=p-PCBTable; //运行中的进程所对应的资源矩阵行下标
//Request[i] <= Need[i]
res=ArrayIsSmaller(Request[row],Need[row],resourceCnt);
if(res==0){
printf("进程对资源的申请量大于它的最大值\n");
return 0;
}
//Request[i] <= Available[i]
res=ArrayIsSmaller(Request[row],Avaliable,resourceCnt);
if(res==0){
printf("可用资源不足\n");
return 0;
}
puts("执行试分配,此时资源状态");
//试分配
ArraySub(Avaliable,Request[row],resourceCnt);
ArrayAdd(Allocation[row],Request[row],resourceCnt);
ArraySub(Need[row],Request[row],resourceCnt);
printBanker(list,n);
//进行安全检测算法
puts("进行安全检测算法");
res=security(list,n);
//取消试分配
ArrayAdd(Avaliable,Request[row],resourceCnt);
ArraySub(Allocation[row],Request[row],resourceCnt);
ArrayAdd(Need[row],Request[row],resourceCnt);
//不安全,取消分配 ,pid进程进入阻塞
if(res==0) {
printf("不存在安全序列\n\n",runPCBHead->next->pid);
}
else{
printf("存在安全序列:");
for(i=0;i<n;i++) printf("%d ",List[i]->pid);
puts(" ");
}
return res;
}
//打印银行家算法相关数据
static void printBanker(PCB_Pointer list[], int n)
{
int i=0,j=0;
int row;
PCB_Pointer p=readyPCBHead->next;
printf("pid ");
for(i=0;i<resourceCnt;i++){
if(i==resourceCnt/2) printf("Max");
else printf(" ");
}
for(i=0;i<resourceCnt;i++){
if(i==resourceCnt/2) printf("Allocation");
else printf(" ");
}
for(i=0;i<resourceCnt;i++){
if(i==resourceCnt/2) printf("Need");
else printf(" ");
}
for(i=0;i<resourceCnt;i++){
if(i==resourceCnt/2) printf("Avalibale");
else printf(" ");
}
puts("\n");
for(i=0;i<n;i++){
row=list[i]-PCBTable;
printf("%d ",list[i]->pid);
ArrayPrint(MaxNeed[row],resourceCnt);
printf(" ");
ArrayPrint(Allocation[row],resourceCnt);
printf(" ");
ArrayPrint(Need[row],resourceCnt);
printf(" ");
if(i==0) ArrayPrint(Avaliable,resourceCnt);
puts("\n");
}
}
int getTimePiece()
{
return timePiece;
}
void requestResource(int req[])
{
int res=0;
int i=0;
int row=runPCBHead->next-PCBTable;
PCB_Pointer p=runPCBHead->next;
printf("请求资源,进行银行家算法检测\n");
ArrayAssign(Request[row],req,resourceCnt);
//把当前运行就绪的进程PCB指针放到List中
List[i++]=p;
p=readyPCBHead->next;
while(p){
List[i++]=p;
p=p->next;
}
puts("当前资源分配状态");
printBanker(List,i);
res=banker(runPCBHead->next,List,i);
if(res==0) {
puts("系统进入阻塞");
runPCBHead->next->status=BLOCK;
}
else {
puts("正式分配资源...");
ArraySub(Avaliable,Request[row],resourceCnt);
ArrayAdd(Allocation[row],Request[row],resourceCnt);
ArraySub(Need[row],Request[row],resourceCnt);
puts("资源分配成功\n");
}
}
//从内存读取一条指令
void readCmd(PCB_Pointer p_pcb,char *cmd)
{
int i=0;
int row=p_pcb->jcb-JCBTable;
int page, block; //页、块
int address;
page=p_pcb->pc/MEMORY_BLOCK_SIZE;
block=pageTable[row][page];
address=block*MEMORY_BLOCK_SIZE+p_pcb->pc%MEMORY_BLOCK_SIZE;
DMARead(address,cmd,CMD_SIZE);
p_pcb->pc+=CMD_SIZE;
cmd[CMD_SIZE]='\0';
}
/**
* 函数名:createProcess
* 功能:创建一个进程,并就绪
* 参数:运行时间,优先级,运行程序
* 返回值:该进程的PCB的指针
*/
int createProcess(JCB_Pointer jcb, int pid, int priority)
{
int i=0;
PCB_Pointer p;
puts("创建进程:");
if(freeCnt==0) return 0;
//分配空闲PCB
p=freePCBHead->next;
freePCBHead->next=freePCBHead->next->next;
freeCnt--;
allocationCnt++;
//设置PCB成员
p->pid=pid;
p->priority=priority;
p->status=READY;
p->pc=0;
p->kind=USER;
p->jcb=jcb;
p->next=NULL;
//如果优先级大于等于最大优先级,则是系统进程
if(priority>=MAX_PRIORITY) p->kind=SYSTEM;
puts("pid priority status kind");
printf("%d %d %d %d\n",p->pid,p->priority,p->status,p->kind);
//计算资源最大需求量
MaxRequest(jcb->file,MaxNeed[p-PCBTable]);
printf("进程%d资源最大需求量:",p->pid);
for(i=0;i<resourceCnt;i++) {
Need[p-PCBTable][i]=MaxNeed[p-PCBTable][i];
printf("%d ",MaxNeed[p-PCBTable][i]);
Allocation[p-PCBTable][i]=0;
}
printf("\n");
puts("创建成功,插入到就绪队列,等待运行...\n");
//插入到就绪队列中
insertPCB(readyPCBHead,p);
readyCnt++;
return 1;
}
/**
* 函数名:destroyProcess
* 功能:销毁释放一个进程
* 参数:PCB指针
* 返回值:1=成功,0=失败
*/
int destroyProcess(PCB_Pointer p_pcb)
{
int i=0;
allocationCnt--;
freeCnt++;
//回收作业
recycleJCB(p_pcb->jcb);
puts("内存回收成功");
puts("触发高级调度中断,准备从后备队列调入作业...");
dispatchJob();
//释放资源
puts("资源释放成功");
ArrayAdd(Avaliable,Allocation[p_pcb-PCBTable],resourceCnt);
puts("触发进程唤醒中断,准备唤醒阻塞的进程...");
wakeupProcess();
//插回空闲队列
p_pcb->next=freePCBHead->next;
freePCBHead->next=p_pcb;
return 1;
}
/**
* 函数名:blockProcess
* 功能:阻塞一个进程
* 参数:PCB指针
* 返回值:1=成功,0=失败
*/
int blockProcess(PCB_Pointer p_pcb)
{
p_pcb->status=BLOCK;
blockCnt++;
// p_pcb->pc-=CMD_SIZE;
//插到阻塞队列
insertPCB(blockPCBHead, p_pcb);
return 1;
}
//唤醒阻塞的进程,把他们重新插到就绪队列中
int wakeupProcess()
{
int res=0,i=0,j=0,row=0;
PCB_Pointer pr,p;
printf("当前阻塞队列:");
printProcess(blockPCBHead);
if(blockPCBHead->next==NULL){
puts("当前阻塞进程为空,无须唤醒进程");
return 1;
}
p=readyPCBHead->next;
while(p){
List[i++]=p;
printf("%d ",p->pid);
p=p->next;
}
puts(" ");
pr=blockPCBHead;
p=blockPCBHead->next;
while(p){
row=p-PCBTable;
printf("进程%d的资源请求数量: ",p->pid);
for(j=0;j<resourceCnt;j++) printf("%d ",Request[row][j]);
puts(" ");
printf("对进程%d进行银行家算法检测\n",p->pid);
puts("当前资源分配状态");
List[i]=p;
printBanker(List,i+1);
res=banker(p,List,i+1);
if(res==1){
puts("检测通过,进行资源分配...");
ArraySub(Avaliable,Request[row],resourceCnt);
ArrayAdd(Allocation[row],Request[row],resourceCnt);
ArraySub(Need[row],Request[row],resourceCnt);
puts("资源分配成功");
puts("将进程插到就绪队列等待运行");
pr->next=p->next;
p->status=READY;
insertPCB(readyPCBHead,p);
p=pr;
}
pr=p;
p=p->next;
}
return 1;
}
void nop()
{
puts("空操作");
return;
}