操作系统进程转换模拟---单链表的使用

新手小白
{
你不大可能看得懂,我也是写给自己看的。。。。
如果不想看,就直接拉到最后,有完整代码。
}
刚刚学习操作系统,还不能做实验,正好复习一下上学期的数据结构。
(发现单链表的有序插入排列都忘了,扣了半天。。还借鉴了别人的代码。)

模拟过程

1.按优先级高低对进程进行调度(可按优先级大小排好顺序),每个进程可有四个状态,即:“就绪”,“阻塞”,“执行”和“终止”(假设优先数越大优先级越高,以及进程的初始状态为就绪状态)。

2。为便于处理,应该随机地赋予所有进程各自的“优先级”和“要求运行的时间片数”,由用户给定。

3.程序中共有3个队列:就绪队列,阻塞队列和消亡(终止)队列。

4.进程每运行一次,优先级数减去1,要求的时间片数减1,如果要求的时间片数为零了,则将其加入消亡队列。否则,将其按照优先级的次序重新加入就绪队列。

5.进程运行过程中,遇到阻塞时,将该进程加入阻塞队列。(提示:可通过随机函数得到随机数,满足某种情况则使之加入到阻塞队列,或人为设置是否阻塞)

6.重复调度,直到就绪队列中所有进程全部运行结束。

首先就要有三个链表
优先级就绪态,阻塞态,终止态

  1. 单链表的有序插入(无头结点)借鉴这位前辈
Status Insert(PCB &L,PCB p){//将各个情况的结点自大到小插入
	PCB pb=NULL,pf=NULL;
	pf=L;
	if(L==NULL){
		L=p;
		p->next=NULL;
	}
	while((p->prior<=pf->prior) && (pf->next!=NULL)){
		pb=pf;					//得到指针的前一个结点的指针
		pf=pf->next;
	}
	if(p->prior>pf->prior){
		if(pf==L){
			L=p;
			p->next=pf;
		}
		else{
			pb->next=p;
			p->next=pf;
		}
	}
	else{
		pf->next=p;
		p->next=NULL;
	}
	return OK;
}

2.在建立玩链表的时候突然发现没有头结点,我记得老师说过要加上头结点便于操作,又要在最后加上。。。很烦

Status CreatReadyPcb(PCB &L_Ready){//就绪递减队列
	InitList(L_Ready);
	PCB p,p1,q;
	p1=L_Ready;
	int i,n;
	printf("输入进程个数:\n");
	scanf("%d",&n);
	printf("输入进程信息:\n");
	for(i=0;i<n;i++){
		p=(PCB)malloc(sizeof(pcb));
		printf("输入进程的内部标识(PID),时间片(time),优先级(prior):\n");
		scanf("%d %d %d",&p->PID,&p->time,&p->prior);
		strcpy(p->state,"ready");
		Insert(L_Ready,p);
	}
	PCB pp;//加入空的头结点,之前忘加了...
	InitList(pp);
	pp->next=L_Ready;
	L_Ready=pp;
	printf("*****优先级就绪队列建立成功!*****\n");
	return OK;
}

3.也就是最头疼的运行,有好几种状态(期间有时候要对链表加上或删除头节点)
我是输入数字代表阻塞的发生

  • 不阻塞
    时间片不为0:
    优先级,时间片都减1
    减一之后判断时间片是否为0
    若为零,加入终止队列
    不为零,则按优先级大小插入就绪链表
    时间片为零
    加入终止链表
  • 阻塞
    加入阻塞链表
void RunPcb(PCB &L_Ready,PCB &L_Block,PCB &L_Finish){
	int n,count=0;
	PCB p=L_Ready->next,p0,p2,pp,p4,pp1;
	PCB p1=L_Finish;
	PCB p5,ppp1;
	printf("请输入阻塞数:\n");
	scanf("%d",&n);
	if(p->time!=n){//不阻塞
		if(p->time!=0){//时间片不为0
			p->time=(p->time)-1;
			p->prior=(p->prior)-1;
			if(p->time!=0){
				fuZhi(p2,p);
				DeleteList(L_Ready);

				p4=L_Ready;//除去头结点
				L_Ready=L_Ready->next;
				free(p4);
				strcpy(p2->state," ready ");
				Insert(L_Ready,p2);//这个函数只能对没有头结点的链表操作

				InitList(pp1);//加入空的头结点
				pp1->next=L_Ready;
				L_Ready=pp1;
				//strcpy(L_Ready->next->state,"ready");
			}
			else{
				fuZhi(p5,p);
				DeleteList(L_Ready);
				strcpy(p5->state," finish ");
				Insert(L_Finish,p5);//这个函数只能对没有头结点的链表操作
			}
		}
		else{//时间片为零
			fuZhi(p2,p);
			DeleteList(L_Ready);
			strcpy(p2->state," finish ");
			Insert(L_Finish,p2);
		}
	}
	else{
		fuZhi(p2,p);
		DeleteList(L_Ready);
		strcpy(p2->state," block ");
		Insert(L_Block,p2);
	}
}

最后就是一些小函数
1.头节点下一个节点的删除:

Status DeleteList(PCB &L){
	int j=0;
	PCB p,q;
	p=L;
	q=p->next;
	p->next=q->next;
	free(q);
	return OK;
}

2.将一个节点属性复制给另一节点

void fuZhi(PCB &p1,PCB &p2){
	InitList(p1);
	p1=(PCB)malloc(sizeof(pcb));
	p1->PID=p2->PID;
	p1->time=p2->time;
	p1->prior=p2->prior;
	p1->next=NULL;
}

3.输出三个链表

void printPcb(PCB &L_Ready,PCB &L_Block,PCB &L_Finish){
	PCB p1,p2,p3;
	p1=L_Ready->next;
	p2=L_Block;
	p3=L_Finish;
	printf("----------优先级就绪队列为:----------\n");
	while(p1!=NULL && p1->prior!=-10){
		printf("PID( %d )---state( %s )---need time( %d )---优先级(%d)\n",p1->PID,p1->state,p1->time,p1->prior);
		p1=p1->next;
	}
	printf("----------阻塞队列为:----------\n");
	while(p2!=NULL && p2->prior!=-10){
		printf("PID( %d )---state( %s )---need time( %d )---优先级(%d)\n",p2->PID,p2->state,p2->time,p2->prior);
		p2=p2->next;
	}
	printf("----------终止队列为:----------\n");
	while(p3!=NULL && p3->prior!=-10){
		printf("PID( %d )---state( %s )---need time( %d )---优先级(%d)\n",p3->PID,p3->state,p3->time,p3->prior);
		p3=p3->next;
	}
}

最后是完整c语言代码,有些操作重复了很多次,是可以用函数块代替的,可是我懒得写了。。。。

#include"stdio.h"
#include"stdlib.h"
#include"string.h"
#include"windows.h"
typedef int Status;
#define OK 1
typedef struct proc{
	int PID;
	char state[10];
	int time;
	int prior;
	struct proc *next;
}*PCB,pcb;
Status InitList(PCB &L){
	L=(PCB)malloc(sizeof(pcb));
	L->PID=0;
	L->time=0;
	L->prior=-10;
	L->next=NULL;
	return OK;
}
Status Insert(PCB &L,PCB p){//将各个情况的结点自大到小插入
	PCB pb=NULL,pf=NULL;
	pf=L;
	if(L==NULL){
		L=p;
		p->next=NULL;
	}
	while((p->prior<=pf->prior) && (pf->next!=NULL)){
		pb=pf;					//得到指针的前一个结点的指针
		pf=pf->next;
	}
	if(p->prior>pf->prior){
		if(pf==L){
			L=p;
			p->next=pf;
		}
		else{
			pb->next=p;
			p->next=pf;
		}
	}
	else{
		pf->next=p;
		p->next=NULL;
	}
	return OK;
}
Status CreatReadyPcb(PCB &L_Ready){//就绪递减队列
	InitList(L_Ready);
	PCB p,p1,q;
	p1=L_Ready;
	int i,n;
	printf("输入进程个数:\n");
	scanf("%d",&n);
	printf("输入进程信息:\n");
	for(i=0;i<n;i++){
		p=(PCB)malloc(sizeof(pcb));
		printf("输入进程的内部标识(PID),时间片(time),优先级(prior):\n");
		scanf("%d %d %d",&p->PID,&p->time,&p->prior);
		strcpy(p->state,"ready");
		Insert(L_Ready,p);
	}
	PCB pp;//加入空的头结点,之前忘加了...
	InitList(pp);
	pp->next=L_Ready;
	L_Ready=pp;
	printf("*****优先级就绪队列建立成功!*****\n");
	return OK;
}

Status DeleteList(PCB &L){
	int j=0;
	PCB p,q;
	p=L;
	q=p->next;
	p->next=q->next;
	free(q);
	return OK;
}
void fuZhi(PCB &p1,PCB &p2){
	InitList(p1);
	p1=(PCB)malloc(sizeof(pcb));
	p1->PID=p2->PID;
	p1->time=p2->time;
	p1->prior=p2->prior;
	p1->next=NULL;
}
void RunPcb(PCB &L_Ready,PCB &L_Block,PCB &L_Finish){
	int n,count=0;
	PCB p=L_Ready->next,p0,p2,pp,p4,pp1;
	PCB p1=L_Finish;
	PCB p5,ppp1;
	printf("请输入阻塞数:\n");
	scanf("%d",&n);
	if(p->time!=n){//不阻塞
		if(p->time!=0){//时间片不为0
			p->time=(p->time)-1;
			p->prior=(p->prior)-1;
			if(p->time!=0){
				fuZhi(p2,p);
				DeleteList(L_Ready);

				p4=L_Ready;//除去头结点
				L_Ready=L_Ready->next;
				free(p4);
				strcpy(p2->state," ready ");
				Insert(L_Ready,p2);//这个函数只能对没有头结点的链表操作

				InitList(pp1);//加入空的头结点
				pp1->next=L_Ready;
				L_Ready=pp1;
				//strcpy(L_Ready->next->state,"ready");
			}
			else{
				fuZhi(p5,p);
				DeleteList(L_Ready);
				strcpy(p5->state," finish ");
				Insert(L_Finish,p5);//这个函数只能对没有头结点的链表操作
			}
		}
		else{//时间片为零
			fuZhi(p2,p);
			DeleteList(L_Ready);
			strcpy(p2->state," finish ");
			Insert(L_Finish,p2);
		}
	}
	else{
		fuZhi(p2,p);
		DeleteList(L_Ready);
		strcpy(p2->state," block ");
		Insert(L_Block,p2);
	}
}
void printPcb(PCB &L_Ready,PCB &L_Block,PCB &L_Finish){
	PCB p1,p2,p3;
	p1=L_Ready->next;
	p2=L_Block;
	p3=L_Finish;
	printf("----------优先级就绪队列为:----------\n");
	while(p1!=NULL && p1->prior!=-10){
		printf("PID( %d )---state( %s )---need time( %d )---优先级(%d)\n",p1->PID,p1->state,p1->time,p1->prior);
		p1=p1->next;
	}
	printf("----------阻塞队列为:----------\n");
	while(p2!=NULL && p2->prior!=-10){
		printf("PID( %d )---state( %s )---need time( %d )---优先级(%d)\n",p2->PID,p2->state,p2->time,p2->prior);
		p2=p2->next;
	}
	printf("----------终止队列为:----------\n");
	while(p3!=NULL && p3->prior!=-10){
		printf("PID( %d )---state( %s )---need time( %d )---优先级(%d)\n",p3->PID,p3->state,p3->time,p3->prior);
		p3=p3->next;
	}
}
int main(){
	PCB L_Ready,L_Block,L_Finish;
	int n;
	printf("******************************\n");
	printf("1--->初始化\n");
	printf("2--->创建就绪队列\n");
	printf("3--->运行\n");
	printf("4--->唤醒\n");
	printf("5--->打印所有队列中的进程信息\n");
	printf("0--->测试结束\n");
	printf("******************************\n");
	while(n!=0){
		printf("请输入你的选择:\n");
		scanf("%d",&n);
		switch(n){
		case 1:
			InitList(L_Block);
			InitList(L_Finish);
			printf("初始化成功!\n");
			break;
		case 2:
			CreatReadyPcb(L_Ready);
			printPcb(L_Ready,L_Block,L_Finish);
			break;
		case 3:
			RunPcb(L_Ready,L_Block,L_Finish);
			printPcb(L_Ready,L_Block,L_Finish);
			break;
		case 4:
		case 5:
			printPcb(L_Ready,L_Block,L_Finish);
			break;
		}
	}
	return 0;
}
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值