0
点赞
收藏
分享

微信扫一扫

操作系统实验——模拟进程调度功能|CSDN创作打卡

1.实验题目:模拟进程调度功能
2.实验目的:通过本实验,进一步掌握进程调度的功能和实现原理。
3.实验环境:
(1)硬件:pc 机。
(2)软件:Windows OS,Visual C++ 6.0(完整绿色版)
4.程序清单:
#include<stdio.h>
#include<string.h>
#include <stdlib.h>
#define LEN sizeof(Pnode)

typedef struct Pnode
{
char pname[30];//进程名
int status;//状态0:就绪,1:执行,2:阻塞
int runtime;//运行时间
int prior;//优先级
struct Pnode *next;//指针
}Pnode, *PCB;

void fprior(PCB ready,PCB run){
PCB pn = run;
PCB py = ready,py2 = ready->next,p = ready->next, p1;
int n = 0;
if(py->next == NULL)
printf(“run empty!\n”);
else{
//删除run队列中的结点
while (py2){
if(py2->prior > p->prior)
p = py2;
py2 = py2->next;
}//end while
//从ready队列中选择优先权最高的进程(假设为p进程)
while(py->next != p){
py = py->next;
}//end while
p1 = p->next;
py->next = p1;
//将p进程从就绪队列中删除;
while(pn->next)
{pn = pn->next;}
pn->next = p;
pn->next->status = 1;
printf("%s \n",p->pname);
//将p进程插入到run队列中
}
}

void ftimeschedule(PCB ready,PCB run,int ts){
PCB py = ready, py1 = ready , pn = run , p , p1;
if(py->next == NULL)
printf(“ready is empty”);
else{
pn->next = NULL;
py = ready;
p = py->next;

	p1 = p->next;
	py->next = p1;//从就绪队列中拿下第一个结点p
	p->status = 1;//将结点p的状态修改为1
	p->next =NULL;
	pn->next = p;//将结点插入run队列中
	p->runtime = p->runtime - ts;//将结点p的运行时间减去一个时间片
    printf("结点名称为: %s",p->pname);  printf("  运行剩余时间为:%d\n",p->runtime);//显示结点p的名称以及剩余时间

	if(p->runtime > 0){
		pn->next = NULL;
		while(py1->next){
			py1 = py1->next;
			printf(py1->pname);
		}
		py1->next = p;
		p->status = 0;
	}//endif 
	else{
        pn->next = NULL;
	}//若剩余时间>0,将结点p从run队列中拿下,修改状态后放入就绪队列的尾部,否则从run队列中删除该结点
printf("you can continue\n");

}
}

void frun(PCB ready, PCB run, int method){
int flag = 1;
while(flag == 1){
switch(method){
case 1: fprior(ready,run); break;
case 2:
int ts;
printf(“please input a timeslice”);
scanf("%d",&ts);//输入系统设定的时间片
ftimeschedule(ready,run,ts); break;
}
printf(“Do you want to run another one 1:yes 0:no :”);
scanf("%d",&flag);
}
}

/create函数:用于将新建的PCB插入就绪队列中/
void fcreate(PCB ready, PCB run, PCB block, int method)
{
PCB p = NULL;
PCB py = ready;
PCB pn = run;
PCB pk = block;
char name[30];
int flag = 1;
while (flag == 1)
{
printf(“please input pname:”);
scanf("%s",name);
//输入新建进程的名称pname;
//在ready、run、block三个队列中查找是否重名
while (py->next)
{
py = py->next;
if (strcmp(py->pname, name) == 0) {
printf(“please input pname again”);
scanf("%s", name);
}
}

	while (pn->next)
	{
		pn = pn->next;
		if (strcmp(pn->pname, name) == 0) {
			printf("please input pname again");
			scanf("%s", name);
		}
	}

	while (pk->next)
	{
		pk = pk->next;
		if (strcmp(pk->pname, name) == 0) {
			printf("please input pname again");
			scanf("%s", name);
		}
	}
	p = (PCB)malloc(LEN);/*申请空白PCB: */
					/*初始化该PCB:输入该进程的相关信息*/
    strcpy(p->pname,name);//Q:strcpy是什么 A:将p的名字复制给pname
	printf("prior: "); scanf("%d", &p->prior);
	printf("runtime: "); scanf("%d", &p->runtime);
	p->status = 0;
	p->next = NULL;
	py->next = p;// 将该节点p插入ready队列;
	printf("Do you want to create anthoer one(1:yes 0:no):");
	scanf("%d", &flag);
}

}

/block函数:用于阻塞正在执行的进程,阻塞后会引起新的进程调度/
void fblock(PCB ready,PCB run,PCB block, int method)
{
PCB pk = block;
PCB pn = run;
PCB p,t;
if(pn->next){
p = pn->next;//从run队列中找到当前正在执行进程的PCB
t = p->next;
pn->next = t;//将该PCB从run队列中取出
p->status = 2;//将其状态修改为2
while(pk->next)
{pk = pk->next;}//让新PCB插入最后队伍
pk->next = p;//将该PCB插入到block队列中
printf(pk->next->pname);
printf(“已阻塞\n”);
frun(ready,run,method);//从ready队列中选择新的进程执行(调用frun函数即可)
}
else
printf(“无可阻塞的进程\n”);
}

/wakeup函数:用于唤醒阻塞队列中的进程,将其插入到就绪队列中/
void fwakeup(PCB ready,PCB run, PCB block, int method)
{
int flag = 1;
PCB pk2 = block->next;
PCB py = ready;
PCB pn = run;
PCB pk = block;
PCB p;
char pname[30];
while(flag==1)
{
printf(“please input the pname you want to wake up:”);
scanf("%s",pname);//输入要唤醒进程的名称pname

 while(pk2)
 {
		 if(strcmp(pk2->pname,pname) == 0){//在block队列中查找是否存在
			 pk2->status=0;   /*将状态修改为0*/  
			 p = pk2->next;
			 pk->next = p;
			 //将该节点从block队列中取下
			 while(py->next){
				 py = py->next;
			 }
			 py->next = pk2;
             //将该节点插入ready队列中;
             printf("已唤醒");
                   if(pn->next == NULL)//如果run队列为空
                   frun(ready,run,method);// 调用frun函数; 
				   break;
		 }//end if

		 else if(pk2->next){
			 pk2 = pk2->next;
			 pk = pk->next;
		 }
		 else
                   printf("the block link is null");//end else 提示“阻塞队列中没有进程”
 }//end whilepk2
           printf("Do you want to wakeup anthoer one(1:yes 0:no):");
              scanf("%d",&flag);
        }//end whileflag
 }//end wakeup

/delete函数:用于撤销进程/
void fdelete(PCB ready,PCB run, PCB block, int method)
{
int flag = 1;
char name[30];
PCB py = ready,py2 = ready->next;
PCB pn = run,pn2 = run->next;
PCB pk = block,pk2 = block->next;
PCB p = NULL;

while(flag == 1)
    {
 printf("please input the pname you want to delete");
 scanf("%s",name);//输入要撤销进程的名称pname;
 
 //在ready、run、block三个队列中查找是否重名
	while (py2)
	{
		if (strcmp(py2->pname, name) == 0) {
			p = py2->next;
			py->next = p;
			printf("ready中的进程已撤销\n");
			break;
		}
		py = py->next;
		py2 = py2->next;
	}

	while (pn2)
	{
		if (strcmp(pn2->pname, name) == 0){
			p = pn2->next;
			pn->next = p;
			printf("run中的进程已撤销\n");
			break;
		}
		pn = pn->next;
		pn2 = pn2->next;
	}

	while (pk2)
	{
		if (strcmp(pk2->pname, name) == 0){
			p = pk2->next;
			pk->next = p;
			printf("block中的进程已撤销\n");
			break;
		}
		pk = pk->next;
		pk2 = pk2->next;
	}

	if(!p)
    printf("the pcb don't exist");//提示“内存中没有该进程”
    if(!run->next)
    frun(ready,run,method); 

           printf("Do you want to delete another one(1:yes 0:no):");
               scanf("%d",&flag);
        }

}

/show函数:显示三个队列中的PCB/
void showlist(char str[], PCB p)
{PCB q;
q=p->next;
puts(str);
if(q==NULL) printf(“NULL\n”);
else
while(q)
{printf(q->pname);//输出q结点的内容;
q=q->next;
}
}

void fshow(PCB ready,PCB run,PCB block)
{
showlist(“Ready List:”,ready);
showlist("\n Run List:",run);
showlist("\n Block List:",block);
printf("\n");
}

void fmenu(int method)
{
	PCB ready, run, block;//定义三个链表的头指针
	int select;//接受用户输入的功能号
	int flag = 1;//控制循环的变量
   /*初始化ready,run,block为带头结点的空链表*/
	ready = (PCB)malloc(LEN);
	ready->next = NULL;
	run = (PCB)malloc(LEN);
	run->next = NULL;
	block = (PCB)malloc(LEN);
	block->next = NULL;

	/*设计整个系统框架*/
	while (flag == 1) /*当flag的值等于0时,程序结束*/
	{  /*构建系统菜单*/
		printf("**********Main    Menu************\n");
		printf("**********1----create***************\n");
		printf("**********2----run***************\n");
		printf("**********3----delete***************\n");
		printf("**********4----block***************\n");
		printf("**********5----wakeup***************\n");
		printf("**********6----show***************\n");
		printf("**********0----return***************\n");
		printf("**************************************\n");
		printf(" input your choice(0-5):");
		/*接收用户从键盘输入的功能号*/
		scanf("%d", &select);

		/*函数调用*/
		switch (select)
		{
		case 1: fcreate(ready, run, block, method); break;
		case 2: frun(ready, run, method); break;
		case 3: fdelete(ready,run,block, method);break;
		case 4: fblock(ready,run,block, method);break;
		case 5: fwakeup(ready,run,block, method);break;
		case 6: fshow(ready,run,block);break;
		case 0: flag=0;break;
		default: printf("input error!");break;
		}/*end switch*/
	}/*end while*/
}/*end main*/


void main(){
	int flag = 1;
	int select;
	while(flag == 1){
		printf("系统调度算法\n");
		printf("1---高优先权优先调度\n");
		printf("2---时间片轮转调度\n");
		printf("0---退出\n");
		printf("请输入选择:");
		scanf("%d",&select);
		switch(select){

case 1:
case 2: fmenu(select); break;
case 0: flag = 0; break;
default: printf(“input error!\n”); break;
}//end switch
}
}
5.调试程序时出现问题说明及解决的方法

举报

相关推荐

0 条评论