Lernen der Prozesswarteschlange basierend auf dem Betriebssystem (C, DevC++)

Inhaltsverzeichnis

  1. Versuchszweck 1
  2. Experimentinhalt 1
    1. Prozessorplanung: 1
    2. Grundlegende Speicherverwaltung: 1
    3. Jobprozesssteuerung: 1
  3. Experimentelle Umgebung 2
  4. Systemanalyse und Design 2
    1. JCB, PCB-Link-Organisation 2
    2. Seitentabelle 2
    3. Bitansicht 2
    4. Banker-Algorithmus-bezogene Datenstruktur 2
    1. Job-Planung mit hohem Antwortverhältnis 2
    2. Prozessprioritätsplanung 3
    3 .Der Job ist in den Speicher übertragen 4.
    Es ist lediglich erforderlich, die vom Job belegte Bitansicht auf 0 zu setzen 6
    5. Prozesserstellung 6
    Funktion: Blockieren Sie den Prozess und fügen Sie ihn in die Blockierungswarteschlange ein 8
    10. Der Prozess simuliert die Ausführung von s 9
  5. Wenn ein Prozess Ressourcen anfordert, rufen Sie den Banker-Algorithmus zur Erkennung 15 auf
  6. Wenn die Ressourcenzuweisung fehlschlägt, gelangt der Prozess in die Blockierungswarteschlange 16

Betriebssystem Windows 7/10
Programmiersprache und Tools C, DevC++
Konfigurationsdatei Keine
Bemerkungen

4. Systemanalyse und -design
(1) Datenstruktur

1. JCB, PCB-Link-Organisation
JCB verfügt über zwei Warteschlangen: Backup-Warteschlange und laufende Warteschlange.
PCB verfügt über 4 Warteschlangen: Leerlaufwarteschlange, Bereitschaftswarteschlange, Laufwarteschlange und Blockierungswarteschlange.
Die Warteschlange ist eine einfach verknüpfte Listenwarteschlange.
Bei JCB sind die beiden Warteschlangen unabhängig und jeder Knoten wird dynamisch zugewiesen. Für PCB wurden alle Knoten vom System zugewiesen und ein Array wird zum Speichern dieser Knoten verwendet.
2. Seitentabelle
Die Seitentabelle ist eine sequentielle Tabelle, deren Größe der Anzahl der Speicherblöcke entspricht, und jeder Prozess verfügt über eine Seitentabelle. Der Index der Sequenztabelle stellt die Seitennummer des Jobs dar, und der Inhalt stellt die Speicherblocknummer dar, die der Seitennummer entspricht.
3. Bitansicht
Die Bitansicht ist eine Sequenztabelle, deren Größe der Anzahl der Speicherblöcke/8 entspricht und ein Bit einen Speicherblock darstellt. Byte Nummer i Bit Nummer j repräsentiert den Speicherblock mit der Nummer 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;
}


Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein

Ich denke du magst

Origin blog.csdn.net/sheziqiong/article/details/130740688
Empfohlen
Rangfolge