OS实验之进程调度

操作系统实验之优先级进程调度

自己写的进程调度代码,写完还是很用成就感的,代码里都有注释,就不多说了,直接上完整代码
运行环境:windows11,编译器:dev-c++

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BLOCKED -1
#define READY 0
#define RUNNING 1
#define FREE 0
#define BUSY 1

typedef struct rcb RCB;

typedef struct prs{	//记录进程占用的资源 
	int rid;
	RCB *rcb;
	struct prs *next;
}PRS;

typedef struct pcb{	//进程控制块 
	int pid;
	char name[10];
	short type;
	int prio;
	PRS *rsc;
	struct pcb *next;
}PCB;

typedef struct rcb{	//资源控制块 
	int rid;
	int pid;
	short state;
	PCB *pHead;
	struct rcb *next;
}RCB;

PCB *ruHead;	//正在执行的进程 
PCB *reHead;	//就绪进程
RCB *rescs;	//所有资源
int PID = 1;	//进程号计数值 


char* getstr(int len);	//解析命令
void create(char *pname, int prio);	//创建进程 
void request(int rid);	//申请资源
void release(int rid);	//释放资源
void kill(int pid);	//删除进程
void kill_rel(PCB *p);	//删除进程时释放资源
void inquire(char *name);	//查询进程信息
void init();	//初始化
void running();	//输出正在运行的进程
void re2ru();	//检查就绪队列,调整运行进程状况
void Rel_resc(RCB *q, PCB *p);	//对于被释放的资源,检查有无阻塞进程并处理

int main(){
	init();
	getchar();
	char cmd[20], *s, para[10][10];
	int i, j, k;
	while(1){
		running();
		printf(">");
		s = getstr(sizeof(cmd));
		strcpy(cmd, s);
		free(s);
		i = 0;
		k = 0;
		do{
			s = (char*)malloc(10*sizeof(char));
			j = 0;
			for(; cmd[i] != ' ' && i < strlen(cmd); i++){
				*(s+j) = cmd[i];
				j++;
			}
			*(s+j) = '\0';
			strcpy(para[k], s);
			k++;
			i++;
			free(s);
		}while(i < strlen(cmd));
		if(strcmp(para[0], "cr") == 0) create(para[1], atoi(para[2]));
		else if(strcmp(para[0], "rq") == 0) request(atoi(para[1]));
		else if(strcmp(para[0], "rl") == 0) release(atoi(para[1]));
		else if(strcmp(para[0], "kl") == 0) kill(atoi(para[1]));
		else if(strcmp(para[0], "inq") == 0) inquire(para[1]);
		else if(strcmp(para[0], "exit") == 0){
			printf("退出进程!");
			break;
		}
		else printf("命令输入错误,请重新输入!\n");
	}
	return 1;
}

//解析命令 
char* getstr(int len){
	int i=0;
	char *p, c;
	p = (char*)malloc(len*sizeof(char));
	do{
		if(i == len){
			printf("命令过长\n");
			break;
		}
		c = getchar();
		if(c == '\n') continue;
		*(p+i)=c;
		i++;
	}while(c!='\n');
	if(i<len-1) *(p+i) = '\0';
	return p;
}

//初始化 
void init(){
	int rsum, i;
	RCB *p;
	//进程队列初始化
	ruHead = (PCB*)malloc(sizeof(PCB));
	ruHead->type = RUNNING;
	ruHead->next = NULL;
	ruHead->prio = 0;
	ruHead->pid = 0;
	memset(ruHead->name, 0, 10);
	reHead = (PCB*)malloc(sizeof(PCB));
	reHead->type = READY;
	reHead->next = NULL;
	reHead->prio = 0;
	reHead->pid = 0;
	//资源序列初始化 
	rescs = (RCB*)malloc(sizeof(RCB));
	rescs->pHead = NULL;
	rescs->rid = 0;
	rescs->pid = 0;
	rescs->state = FREE;
	rescs->next = NULL;
	printf("输入需求资源数量:");
	scanf("%d", &rsum);
	for(i=0;i<rsum;i++){
		RCB *p1, *node;
		node = (RCB*)malloc(sizeof(RCB));
		node->rid = i+1;
		node->pid = 0;
		node->state = FREE;
		node->pHead = NULL;
		node->next = NULL;
		for(p1=rescs;p1->next!=NULL;p1=p1->next);
		p1->next = node;
	}
	printf("资源列表:\n");
	for(p=rescs->next;p!=NULL;p=p->next){
		printf("资源id:%d,", p->rid);
		if(p->state==FREE) printf("空闲\n");
		else printf("占用\n");
	}
	printf("初始化完毕\n");
}

//输出正在运行的进程
void running(){
	PCB *p = ruHead->next;
	if(p==NULL) printf("*无运行进程\n");
	else printf("*进程%s正在运行\n", p->name); 
}

//创建一个进程
void create(char *pname, int prio){
	PCB *node, *p, *q;
	//创建进程PCB 
	node = (PCB*)malloc(sizeof(PCB));
	node->pid = PID++;
	node->prio = prio;
	strcpy(node->name, pname);
	node->type = READY;
	node->next = NULL;
	node->rsc = NULL;
	//把进程PCB按照优先级插入就绪队列 
	p = reHead->next;
	if(p==NULL) reHead->next = node;
	else{
		for(q=reHead;p!=NULL&&p->prio>=node->prio;p=p->next) q=p;
		q->next = node;
		node->next = p;
	}
	re2ru();
	printf(" 创建进程%s,优先级为%d\n", pname, prio);
}

//申请资源
void request(int rid){
	PCB *p = ruHead->next;
	RCB *q = rescs->next;
	for(;q!=NULL&&q->rid!=rid;q = q->next);
	if(q==NULL){
		printf("没有资源%d\n", rid);
		printf("资源列表:\n");
		for(q=rescs->next;q!=NULL;q=q->next){
			printf("资源id:%d,", q->rid);
			if(q->state==FREE) printf("空闲\n");
			else printf("进程%d占用\n", q->pid);
		}
	}
	else{
		//资源未被占用
		if(q->state == FREE){
			PRS *pr, *npr;
			pr = (PRS*)malloc(sizeof(PRS));
			pr->rcb = q;
			pr->rid = q->rid;
			pr->next = NULL;
			q->state = BUSY;
			q->pid = p->pid;
			npr = p->rsc;
			if(npr == NULL) p->rsc = pr;
			else{
				for(;npr->next!=NULL;npr=npr->next);
				npr->next = pr;
			}
			printf("已为进程%s分配资源%d\n", p->name, q->rid);
		}
		//资源已被占用
		else{
			PCB *n1, *n2;
			n1 = q->pHead;
			p->type = BLOCKED;
			ruHead->next = NULL;
//			for(n2=blHead;n2->next!=NULL;n2=n2->next);
//			n2->next = p;
			if(n1 == NULL) q->pHead = p;
			else{
				if(p->prio > n1->prio){
					q->pHead = p;
					p->next = n1;
				}
				else{
					for(;n1!=NULL&&n1->prio>=p->prio;n1=n1->next) n2=n1;
					n2->next = p;
					p->next = n1;
				}
			}
			re2ru();
			printf("资源%d被%d号进程占用,进程%s阻塞\n", q->rid, q->pid, p->name);
		}
	}
	
}

//释放资源
void release(int rid){
	PCB *p = ruHead->next;
	RCB *q = rescs->next;
	for(;q!=NULL&&q->rid!=rid;q = q->next);
	if(q==NULL){
		printf("没有资源%d\n", rid);
		printf("资源列表:\n");
		for(q=rescs->next;q!=NULL;q=q->next){
			printf("资源id:%d,", q->rid);
			if(q->state==FREE) printf("空闲\n");
			else printf("进程%d占用\n", q->pid);
		}
	}
	else{
		//资源被正在运行的进程占用
		if(q->pid == p->pid){
			PRS *n1, *n2;
			//先把资源从进程占用资源中删除 
			n1 = p->rsc;
			if(n1->rid == q->rid){
				p->rsc = n1->next;
			}
			else{
				for(;n1->rid != q->rid;n1=n1->next) n2=n1;
				n2->next = n1->next;
			}
			//检查此资源下有无阻塞进程并处理 
			Rel_resc(q, p);
		}
		//资源被其他进程占用 
		else printf("进程%s没有占用资源%d,资源被%d号进程\n", p->name, q->rid, q->pid);
	}
}

//删除进程的资源释放 
void kill_rel(PCB *p){
	PRS *pr=p->rsc;
	if(pr!=NULL){
		RCB *q;
		for(;pr!=NULL;pr=pr->next){
			RCB *q = pr->rcb;
			Rel_resc(q, p); 
		}
	}
}

//关闭进程
void kill(int pid){
	PCB *p, *p1;
	p = ruHead->next;
	//删除运行进程 
	if(p->pid == pid){
		ruHead->next = NULL;
		kill_rel(p); 
		printf("进程%d已被删除!\n", pid);
		re2ru();
		return;
	}
	p = reHead;
	if(p!=NULL) for(;p!=NULL&&p->pid!=pid;p=p->next) p1=p;
	//删除就绪进程 
	if(p!=NULL){
		p1->next = p->next;
		kill_rel(p);
		printf("进程%d已被删除!\n", pid);
		re2ru();
		return;
	}
	RCB *q = rescs->next;
	//删除阻塞进程 
	while(q!=NULL){
		p = q->pHead;
		if(p!=NULL) for(;p!=NULL&&p->pid!=pid;p=p->next) p1=p;;
		if(p==NULL) q=q->next;
		else break;
	}
	if(q!=NULL){
		p1->next = p->next;
		kill_rel(p);
		printf("进程%d已被删除!\n", pid);
		re2ru();
		return;
	}
	else printf("查无进程%d\n", pid);
}

//查询进程信息
void inquire(char *name){
	PCB *p;
	p = ruHead->next;
	if(strcmp(name, p->name) == 0){
		printf("进程id:%d,状态:运行,优先级:%d\n", p->pid, p->prio);
		return;
	}
	p = reHead->next;
	for(;p!=NULL&&strcmp(name, p->name)!=0;p=p->next);
	if(p!=NULL){
		printf("进程id:%d,状态:就绪,优先级:%d\n", p->pid, p->prio);
		return;
	}
	RCB *q = rescs->next;
	while(q!=NULL){
		p = q->pHead;
		for(;p!=NULL&&strcmp(name, p->name)!=0;p=p->next);
		if(p==NULL) q=q->next;
		else break;
	}
	if(q!=NULL){
		printf("进程id:%d,状态:阻塞,阻塞资源:%d\n", p->pid, q->rid);
		return;
	}
	printf("查无进程%s!\n");
}

//检查就绪进程,调整运行队列
void re2ru(){
	PCB *p1, *p2;
	p1 = ruHead->next;
	p2 = reHead->next;
	if(p2!=NULL){
		//无进程运行 
		if(p1 == NULL){
			ruHead->next = p2;
			reHead->next = p2->next;
			p2->type = RUNNING;
		}
		//有进程运行时 
		else{
			if(p2->prio>p1->prio){
				ruHead->next = p2;
				reHead->next = p2->next;
				p2->type = RUNNING;
				PCB *p, *q;
				p = reHead->next;
				if(p == NULL) reHead->next = p1;
				else{
					for(q = reHead;p!=NULL&&p->prio>=p1->prio;p=p->next) q = p;
					q->next = p1;
					p1->next = p;
				}
				p1->type = READY;
			}
		}
	}	
}

//处理释放的资源
void Rel_resc(RCB *q, PCB *p){
	PCB *s1, *s2, *s3;
	PRS *n1; 
	s1 = q->pHead;
	//有被此资源阻塞的进程 
	if(s1 != NULL){
		q->pHead = s1->next;
		q->pid = s1->pid;
		s1->next = NULL;
		PRS *node;
		node = (PRS*)malloc(sizeof(PRS));
		node->rcb = q;
		node->rid = q->rid;
		node->next = NULL;
		n1 = s1->rsc;
		if(n1 == NULL) s1->rsc = node;
		else{
			for(;n1->next!=NULL;n1=n1->next);
			n1->next = node;
		}
		s1->type = READY;
		s2 = reHead->next;
		if(s2==NULL) reHead->next=s1;
		else{
			if(s1->prio>s2->prio){
				reHead->next = s1;
				s1->next = s2;
			}
			else{
				for(;s2->prio>=s1->prio&&s2!=NULL;s2=s2->next) s3=s2;
				s3->next = s1;
				s1->next = s2;
			}
		}
		re2ru();
	}
	//没有被此资源阻塞的进程
	else q->pid = 0;
	printf("资源%d已被进程%s释放\n", q->rid, p->name);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值