【实验名称】进程调度模拟实验                     

 

【实验目的】

1. 掌握进程控制块的作用和实现技术;

2. 熟悉操作系统的进程调度算法及实现方法。

 

【实验原理】

进程调度算法:采用最高优先数优先的调度算法(即把处理机分配给优先数最高的进程)和先来先服务算法。每个进程有一个进程控制块(PCB)表示。进程控制块可以包含:进程名、优先数、到达时间、需要运行时间、已用CPU时间、进程、状态等等。

进程的优先数及需要的运行时间可以事先人为地指定。进程的到达时间为进程输入的时间。进程的运行时间以时间片为单位进行计算。每个进程的状态可以是就绪 W(Wait )、运行R(Run)、或完成F(Finish )三种状态之一。

 

【实验内容】

实验内容:用高级语言编写和调试一个 N个进程共行的进程调度程序。 进程调度算法:采用最高优先数优先的调度算法(即把处理机分配给优先数最高的进程)和先来先服务算法。

 

代码:

#include <iostream>
using namespace std;

//进程类
class pcb
{
public:
	//构造函数
	pcb(char Name[20], int Rank, int Needtime)
	{
		strcpy(name, Name);
		state = 'W';
		rank = Rank;
		needtime = Needtime;
		runtime = 0;
		next = NULL;
	}
	char name[20];
	char state;
	int rank;
	int needtime;
	int runtime;
	pcb* next;
};
pcb *ready = NULL, *now = NULL;

//输出进程
void output(pcb *point)
{
	cout << ".................................................";
	cout << "\n name \t state \t rank \t needtime \t runtime" << endl;
	cout << "|" << point->name << "\t";
	cout << "|" << point->state << "\t";
	cout << "|" << point->rank << "\t";
	cout << "|" << point->needtime << "\t\t";
	cout << "|" << point->runtime << "\t" << endl;
	cout << "................................................." << endl;
}

//进程依次排序
void sort(pcb *point)
{
	if (ready == NULL)//若链表为空
	{
		ready = point;
	}
	else
	{
		pcb *point1 = ready, *point2 = ready->next;
		if (point->rank > point1->rank)//若为优先等级最高,放在队首
		{
			point->next = ready;
			ready = point;
		}
		else
		{
			while (point2 != NULL)//遍历链表,直到找到合适位置
			{
				if (point->rank > point2->rank)
				{
					point1->next = point;
					point->next = point2;
					break;
				}
				point1 = point2;
				point2 = point2->next;
			}
			if (point2 == NULL)//若为优先等级最低,放在队尾
			{
				point1->next = point;
			}
		}
	}
}

//进程结束函数,打印已完成进程,释放内存
void finish(pcb *point)
{
	point->state = 'F';
	cout << "################################################" << endl;
	cout << "**************** 进程" << point->name << "已经完成 *****************" << endl;
	cout << "\n name \t state \t rank \t needtime \t runtime" << endl;
	cout << "|" << point->name << "\t";
	cout << "|" << point->state << "\t";
	cout << "|" << point->rank << "\t";
	cout << "|" << point->needtime << "\t\t";
	cout << "|" << point->runtime << "\t" << endl;
	cout << "################################################" << endl;
	delete(point);
	point = NULL;
}

//运行一个单位时间
void running()
{
	now = ready;
	ready = ready->next;
	now->next = NULL;
	now->state = 'R';
	now->rank--;
	now->runtime++;
	
	if (now->needtime == now->runtime)
	{
		//若当前进程执行完毕
		finish(now);
		now = NULL;
	}
	else
	{
		//若当前进程没有执行完毕
		cout << "************* 当前正在运行的进程是 **************" << endl;
		output(now);
	}
	//打印就绪队列
	cout << "************* 当前就绪队列状态为 ***************" << endl;
	pcb *point = ready;
	while (point != NULL)
	{
		output(point);
		point = point->next;
	}
	//把没执行完的进程重新放入队列
	if (now != NULL)
	{
		now->state = 'W';
		sort(now);
	}
}

int main()
{
	//freopen("in.txt", "r", stdin);
	int t;
	cout<<"**** 输入进程数目:";
	cin >> t;
	cout << endl;
	//进程信息输入
	for (int i = 1; i <= t; i++)
	{
		pcb *temp;
		char name[20];int rank;int needtime;
		cout << "**** 请输入第" << i << "个进程的信息 ****" << endl;
		cout << "请输入该进程的名字:";
		cin >> name;
		cout << "请输入该进程的优先等级:";
		cin >> rank;
		cout << "请输入该进程需要的运行时间:";
		cin >> needtime;
		temp = new pcb(name, rank, needtime);
		sort(temp);
		temp = NULL;
		cout << endl;
	}

	//打印执行前的就绪队列
	cout << "************* 执行前就绪队列排序 ***************" << endl;
	pcb *point = ready;
	while (point != NULL)
	{
		output(point);
		point = point->next;
	}
	cout << "************ 程序准备正式开始执行 **************" << endl;

	//程序开始执行
	char ch;
	while (now != NULL || ready != NULL)
	{
		//一次运行一个单位时间
		cout << "\n\n 按任一键继续......" << endl;
		ch = getchar();
		running();
		cout << endl;
	}
	//所有进程完成
	cout << "\n************************************************" << endl;
	cout << "************* 所有进程均已执行完成 *************" << endl;
	cout << "************************************************\n" << endl;
	return 0;
}

 

运行结果:

 

 

 

 

 

 

从实验结果可以看出,实验成功。

 

【小结或讨论】

这里我想总结一下在C++实现时遇到的一些困难。比如在给指针开辟内存时,原先C语言结构体需要使用malloc函数给指针分配内存空间,而在C++中不能这样做。我一开始使用pcb temp(name, rank, needtime)直接对每个对象进行初始化,但是因为需要循环输入,发现这一语句会导致循环输入时异常。我仔细调试了一下,发现temp分配的地址并不会随着循环重新分配,所以新的输入数据会将旧的输入数据覆盖,我在网上找了找解决方法,最后使用pcb *temp; temp = new pcb(name, rank, needtime); 在堆内存中动态开辟空间创建对象,修改过后实验成功。

这次实验的主要难点我觉得是在调度排序算法上。这个调度排序实际上是链表排序,首先按优先级排序,若优先级相同则先来的排在前面。这里的逻辑判断顺序问题是需要着重注意的,特别要留意对队首和队尾的特殊处理上,在遍历队列时也要注意使用两个指针记录插入点的前后两个节点,毕竟这是一个单向链表。我的逻辑判断顺序是:链表是否为空;若为优先等级最高,放在队首;遍历链表,直到找到合适位置;若为优先等级最低,放在队尾。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐