基于操作系统实现的进程队列学习(C,DevC++)

目录

  1. 实验目的 1
  2. 实验内容 1
    1.处理机调度: 1
    2.基本存储管理: 1
    3.作业进程控制: 1
  3. 实验环境 2
  4. 系统分析与设计 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
  5. 当进程请求资源,调用银行家算法进行检测 15
  6. 当资源分配失败时,进程进入阻塞队列 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;
}


在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/sheziqiong/article/details/130740688