操作系统实验之优先级进程调度
自己写的进程调度代码,写完还是很用成就感的,代码里都有注释,就不多说了,直接上完整代码
运行环境: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);
}