操作系统:进程控制和内存管理模拟实现

要求

(1)设计一个允许n个进程并发运行的OS进程管理模拟程序,模拟实现创建新进程原语、阻塞进程原语、唤醒进程原语,终止进程原语、调度进程原语等功能;每个进程用一个PCB表示,其内容可根据具体情况设置。进程调度算法可选择 FCFS、时间片轮转或其他任意一种。内存分配可采用可变分区策略+最佳适应算法(或页式等其他内存分配方案,自选一种),进程创建时需为进程分配内存空间,进程终止时需要回收进程的内存空间。
(2)程序在运行过程中能显示或打印各进程的状态及有关参数的变化情况,以便观察诸进程的运行过程及系统的管理过程。

设计

  1. 将进程设计为4个状态:创建、就绪、运行和阻塞。
    在这里插入图片描述
  2. 进程调度采用优先级调度算法,是把处理机分配给就绪队列中优先级最高的进程
  3. 可变分区分配根据进程的实际需要,动态地为之分配内存空间。为了实现可变分区分配,系统必须配备相应的数据结构,用以描述空闲分区和已分配分区的情况,为分配提供依据。
  4. 最佳适应算法是指每次分配内存时,将满足要求、又是最小调度空闲分区分配出去。为了加速寻找,该算法要求将所有的空闲分区按照分区大小排列。

代码

#include<iostream>

using namespace std;


/*
优先级调度算法,优先级大的进程先运行
可变分区策略+最佳适应算法
*/


/*进程控制块结构体*/
class PCB
{
public:
	int id;             //进程id
	int state;          //进程状态     -2创建, -1就绪, 0运行, 1阻塞
	
	int priority;       //优先级
	
	int needTime;       //运行完毕所需时间
	int arrivedTime;    //已运行时间
	
	int sliceTime;      //时间片时间 初始为5
	
	int memorySize;     //内存大小
	int memoryStart;    //内存起始
	PCB* next;
};

/*进程队列*/
PCB* CreateTask;      //创建
PCB* ReadyTask;       //就绪
PCB* RunningTask;     //运行
PCB* BlockTask;       //阻塞

/*进程id*/
int id = 1;

/*空闲分区表*/
class Table
{
public:
	int id;           //分区号,从0开始
	int size;         //分区大小
	int address;      //分区始址
	int state = 0;    //状态    0空闲, 1占用
};
Table table[5];

/*函数声明*/
void ProcessControl();          //进程控制程序
void createProcess();           //创建进程
void deleteProcess();           //撤销进程
void blockProcess();            //阻塞进程
void awakeProcess();            //唤醒进程
void runProcess();              //运行进程
void scheduleProcess();         //进程调度
void getBigPriorityProcess();   //将最大优先级的就绪进程调度到运行进程
void showProcess();             //显示所有进程状态
void printProcess(PCB* test);   //显示单个进程状态

int main()
{
	CreateTask = NULL;
	RunningTask = NULL;
	ReadyTask = NULL;
	BlockTask = NULL;

	for (int i = 0; i < 5; i++) //空闲分区表始址为0,默认每个分区大小分别为5,6,7,8,9
	{
		table[i].id = i;
		table[i].size = 5 + i;
		table[i].address = i * 5;
	}

	cout << "********************************************************************************************************" << endl;
	cout << "*****************************************进程控制和内存管理模拟程序*************************************" << endl;
	cout << "********************************************************************************************************" << endl;

	while (1)
	{
		ProcessControl();
	}
	return 0;
}

/*进程控制程序    每执行一次,当前运行进程时间片减一     创建进程不占当前执行进程时间*/
void ProcessControl()
{
	int select;
	cout << endl;
	cout << "-----------1.创建进程-------------------" << endl;
	cout << "-----------2.阻塞进程-------------------" << endl;
	cout << "-----------3.唤醒进程-------------------" << endl;
	cout << "-----------4.撤销进程-------------------" << endl;
	cout << "-----------5.无操作---------------------" << endl;
	cout << "-----------6.退出-----------------------" << endl;
	cout << "请输入你的选择(1--6):";

	do
	{
		cin >> select;
	} while (select < 1 && select>6);

	switch (select)
	{
	case 1:
		createProcess();
		break;
	case 2:
		blockProcess();
		break;
	case 3:
		awakeProcess();
		break;
	case 4:
		deleteProcess();
		break;
	case 5:
		break;
	case 6:
		cout << endl << "******************************************************结束**********************************************" << endl;
		exit(0);
		break;
	default:
		return;
	}
	runProcess();
	showProcess();
}

/*创建进程   将已分配内存的进程添加到就绪队列的队尾*/
void   createProcess()
{
	cout << endl << endl << "创建进程开始" << endl;

	if (CreateTask == NULL)  //判断创建队列是否为空
	{
		CreateTask = (PCB*)malloc(sizeof(PCB));

		CreateTask->id = id++;

		cout << "进程优先级:";
		cin >> CreateTask->priority;

		cout << "进程运行需要的时间:";
		cin >> CreateTask->needTime;

		cout << "进程需要的内存:";
		cin >> CreateTask->memorySize;

		CreateTask->arrivedTime = 0;
		CreateTask->state = -2;
		CreateTask->sliceTime = 0;
		CreateTask->next = NULL;
	}
	else
	{
		PCB* test = CreateTask;
		while (test->next != NULL)
		{
			test = test->next;
		}
		test->next = (PCB*)malloc(sizeof(PCB));

		test->next->id = id++;

		cout << "进程优先级:";
		cin >> test->next->priority;

		cout << "进程运行需要的时间:";
		cin >> test->next->needTime;

		cout << "进程需要的内存:";
		cin >> test->next->memorySize;

		test->next->arrivedTime = 0;
		test->next->state = -2;
		test->next->next = NULL;
		test->next->sliceTime = 0;
		test = test->next;
	}

	PCB* test = CreateTask;
	while (test != NULL)
	{
		if (test->state == -2)
		{
			for (int i = 0; i < 5; i++)
			{
				if (table[i].state == 0 && test->memorySize <= table[i].size)
				{
					test->memoryStart = table[i].address;
					test->state = -1;
					table[i].state = 1;

					break;
				}
			}
		}
		if (test->state == -1)
		{
			if (test != NULL)
			{
				if (ReadyTask == NULL) //判断就绪队列是否为空
				{
					ReadyTask = (PCB*)malloc(sizeof(PCB));
					ReadyTask->id = test->id;
					ReadyTask->priority = test->priority;
					ReadyTask->needTime = test->needTime;
					ReadyTask->memorySize = test->memorySize;
					ReadyTask->memoryStart = test->memoryStart;
					ReadyTask->arrivedTime = 0;
					ReadyTask->state = -1;
					ReadyTask->sliceTime = 0;
					ReadyTask->next = NULL;
				}
				else
				{
					PCB* test1 = ReadyTask;
					while (test1->next != NULL)
					{
						test1 = test1->next;
					}
					test1->next = (PCB*)malloc(sizeof(PCB));
					test1->next->id = test->id;
					test1->next->priority = test->priority;
					test1->next->needTime = test->needTime;
					test1->next->memorySize = test->memorySize;
					test1->next->memoryStart = test->memoryStart;
					test1->next->arrivedTime = 0;
					test1->next->state = -1;
					test1->next->next = NULL;
					test1->next->sliceTime = 0;
					test1 = test1->next;
				}
				if (test == CreateTask)
				{
					CreateTask = test->next;
				}
				else
				{
					PCB* test1 = CreateTask;
					while (test1->next->state != -1)
					{
						test1 = test1->next;
					}
					test1->next = test->next;
				}
			}
		}
		test = test->next;
	}

	cout << endl;
}

/*撤销进程*/
void deleteProcess()
{
	//撤销运行进程
	char select;
	cout << endl << "撤销创建进程输入A/a  撤销运行进程输入B/b  撤销就绪进程输入C/c  撤销阻塞进程输入D/d   :";
	do
	{
		select = getchar();
	} while (select != 'A' && select != 'a' && select != 'B' && select != 'b' && select != 'C' && select != 'c' && select != 'D' && select != 'd');

	//撤销创建进程
	if (select == 'A' || select == 'a')//进行撤销
	{
		if (CreateTask == NULL)
		{
			cout << "无创建进程" << endl;
		}
		else
		{
			PCB* test = CreateTask;
			while (test != NULL) //循环输出处于创建队列的进程信息
			{
				cout << endl << "     进程名     优先级     需要时间     已用时间     剩余时间片     进程状态" << endl;
				cout << "        " << test->id;
				cout << "          " << test->priority;
				cout << "           " << test->needTime;
				cout << "           " << test->arrivedTime;
				cout << "             " << test->sliceTime;
				cout << "             " << test->state;
				cout << endl;

				cout << "是否撤销本进程(撤销Y/y  不撤销N/n):";
				do
				{
					select = getchar();
				} while (select != 'y' && select != 'n' && select != 'Y' && select != 'N');

				if (select == 'y' || select == 'Y')  //选择撤销该进程
				{
					//从进程队列删除撤销进程
					if (CreateTask == test)     //判断是否为队首
					{
						CreateTask = test->next;
					}
					else    //撤销进程非队首
					{
						PCB* test1 = CreateTask;
						while (test1->next != test)
						{
							test1 = test1->next;
						}
						test1->next = test->next;
					}
					free(test);
					scheduleProcess();
					return;
				}
				test = test->next;
			}
		}
	}
	//撤销运行进程
	if (select == 'B' || select == 'b') //进行撤销
	{
		if (RunningTask == NULL)
		{
			cout << "无运行进程" << endl;
		}
		else
		{
			for (int i = 0; i < 5; i++)
			{
				if (RunningTask->memoryStart == table[i].address)
				{
					table[i].state = 0;
				}
			}
			free(RunningTask);
			RunningTask = NULL;
			scheduleProcess();
			return;
		}
	}
	//撤销就绪进程
	if (select == 'C' || select == 'c')//选择撤销
	{
		if (ReadyTask == NULL)
		{
			cout << "无就绪进程" << endl;
		}
		else
		{
			PCB* test = ReadyTask;
			while (test != NULL) //循环输出阻塞进程信息
			{
				cout << endl << "     进程名     优先级     需要时间     已用时间     剩余时间片     进程状态" << endl;
				cout << "        " << test->id;
				cout << "          " << test->priority;
				cout << "           " << test->needTime;
				cout << "           " << test->arrivedTime;
				cout << "             " << test->sliceTime;
				cout << "             " << test->state;
				cout << endl;

				cout << "是否撤销本进程(撤销Y/y  不撤销N/n) :";
				do
				{
					select = getchar();
				} while (select != 'y' && select != 'n' && select != 'Y' && select != 'N');
				if (select == 'y' || select == 'Y')  //选择撤销该进程
				{
					//从进程队列删除撤销进程
					if (ReadyTask == test)     //判断是否为队首
					{
						ReadyTask = test->next;
					}
					else    //撤销进程非队首
					{
						PCB* test2 = ReadyTask;
						while (test2->next != test)
						{
							test2 = test2->next;
						}
						test2->next = test->next;
					}
					for (int i = 0; i < 5; i++)
					{
						if (test->memoryStart == table[i].address)
						{
							table[i].state = 0;
						}
					}
					free(test);
					scheduleProcess();
					return;
				}
				test = test->next;
			}
		}
	}
	//撤销阻塞进程
	if (select == 'D' || select == 'd')//选择撤销
	{
		if (BlockTask == NULL)
		{
			cout << "无阻塞进程" << endl;
		}
		else
		{
			PCB* test = BlockTask;
			while (test != NULL) //循环输出阻塞进程信息
			{
				cout << endl << "     进程名     优先级     需要时间     已用时间     剩余时间片     进程状态" << endl;
				cout << "        " << test->id;
				cout << "          " << test->priority;
				cout << "           " << test->needTime;
				cout << "           " << test->arrivedTime;
				cout << "             " << test->sliceTime;
				cout << "             " << test->state;
				cout << endl;

				cout << "是否撤销本进程(撤销Y/y  不撤销N/n) :";
				do
				{
					select = getchar();
				} while (select != 'y' && select != 'n' && select != 'Y' && select != 'N');
				if (select == 'y' || select == 'Y')  //选择撤销该进程
				{
					//从进程队列删除撤销进程
					if (BlockTask == test)     //判断是否为队首
					{
						BlockTask = test->next;
					}
					else    //撤销进程非队首
					{
						PCB* test3 = BlockTask;
						while (test3->next != test)
						{
							test3 = test3->next;
						}
						test3->next = test->next;
					}
					for (int i = 0; i < 5; i++)
					{
						if (test->memoryStart == table[i].address)
						{
							table[i].state = 0;
						}
					}
					free(test);
					scheduleProcess();
					return;
				}
				test = test->next;
			}
		}

	}

}

/*
阻塞进程程序
*/
void blockProcess()
{
	if (RunningTask == NULL)  //判断当前有无运行进程
	{
		cout << "无运行进程" << endl;
		return;
	}
	RunningTask->state = 1;    //阻塞进程状态默认为1,将进程放入阻塞队列由runProcess()实现
}

/*
唤醒程序,唤醒优先级最大的进程,若有优先级相同进程,唤醒先进入队列的进程
*/
void awakeProcess()
{
	if (BlockTask == NULL) //判断当前有无阻塞进程
	{
		cout << "无阻塞进程" << endl;
		return;
	}
	int max = -100;
	PCB* test = BlockTask;
	while (test != NULL)
	{
		if (max < test->priority)
		{
			max = test->priority;
		}
		test = test->next;
	}
	if (max == BlockTask->priority)     //判断当前要唤醒的进程是否为队首
	{
		//将进程放入就绪队列中
		if (ReadyTask == NULL)//判断就绪队列是否为空
		{
			ReadyTask = BlockTask;
			ReadyTask->state = 0;
			BlockTask = BlockTask->next;
			ReadyTask->next = NULL;
		}
		else  //放到就绪队列队尾
		{
			PCB* test2 = ReadyTask;
			while (test2->next != NULL)
			{
				test2 = test2->next;
			}
			test2->next = BlockTask;
			test2->next->state = -1;
			test2->next->next = NULL;
			BlockTask = BlockTask->next;
		}
	}
	else        //唤醒进程不在队首
	{
		//确定应唤醒进程在阻塞进程队列的位置
		PCB* test3 = BlockTask;
		while (test3->next->priority != max)
		{
			test3 = test3->next;
		}
		//将进程放入就绪队列中
		if (ReadyTask == NULL)  //判断就绪队列是否为空
		{
			ReadyTask = test3->next;
			ReadyTask->state = -1;
			test3->next = test3->next->next;
			ReadyTask->next = NULL;
		}
		else        //放到就绪队列队尾
		{
			PCB* test2 = ReadyTask;
			while (test2->next != NULL)
			{
				test2 = test2->next;
			}
			test2->next = test3->next;
			test2->next->state = -1;
			test3->next = test3->next->next;
			test2->next->next = NULL;
		}
	}
	scheduleProcess();
}

/*进程运行   运行一次时间片时间减1  进程已运行时间加1*/
void runProcess()
{
	if (RunningTask != NULL)
	{
		cout << "进程运行中" << endl;
		RunningTask->arrivedTime += 1;
		RunningTask->sliceTime -= 1;

		if (RunningTask->arrivedTime == RunningTask->needTime) //当运行进程完成
		{
			cout << "进程运行结束" << endl;
			printProcess(RunningTask);
			cout << "进程调度" << endl;
			for (int i = 0; i < 5; i++)
			{
				if (RunningTask->memoryStart == table[i].address)
				{
					table[i].state = 0;
				}
			}
			free(RunningTask);
			RunningTask = NULL;
			scheduleProcess();
		}
		else if (RunningTask->sliceTime == 0)    //当运行进程时间片用完
		{
			///改变进程优先级
			//将运行完进程放回就绪进程
			if (ReadyTask == NULL)
			{
				ReadyTask = RunningTask;
				ReadyTask->state = -1;
			}
			else
			{
				PCB* test = ReadyTask;
				int num = 1;
				while (test->next != NULL)
				{
					num++; //计算就绪进程的数量
					test = test->next;
				}
				test = ReadyTask;
				test->priority += num;
				while (test->next != NULL)
				{
					test = test->next;
					test->priority += 1;
				}
				test->next = RunningTask;
				test->next->state = -1;
				test->next->next = NULL;
			}
			RunningTask = NULL;
			cout << "时间片用完,进程调度" << endl;
			scheduleProcess();
		}
		else if (RunningTask->state > 0)    //当运行进程被阻塞
		{
			//将被阻塞进程放入阻塞进程
			if (BlockTask == NULL)
			{
				BlockTask = RunningTask;
				BlockTask->state = 1;
				BlockTask->next = NULL;
			}
			else
			{
				PCB* test = BlockTask;
				while (test->next != NULL)
				{
					test = test->next;
				}
				test->next = RunningTask;
				test->next->state = 1;
				test->next->next = NULL;
			}
			RunningTask = NULL;
			cout << "运行进程被阻塞,进程调度" << endl;
			scheduleProcess();
		}
	}
	else
	{
		cout << "无运行进程,进程调度" << endl;
		scheduleProcess();
	}
}

/*进程调度*/
void scheduleProcess()
{
	if (RunningTask == NULL || RunningTask->sliceTime == 0 || RunningTask->needTime == RunningTask->arrivedTime || RunningTask->state > 0)    //判断是否符合切换运行进程条件
	{
		cout << "进程调度" << endl;
		if (ReadyTask != NULL)  //判断有无就绪进程
		{
			if (RunningTask == NULL || RunningTask->sliceTime == 0 || RunningTask->needTime == RunningTask->arrivedTime || RunningTask->state > 0)
			{
				getBigPriorityProcess();
			}
			else //运行进程队列不需切换进程但进入
			{
				cout << "进程调度出现错误" << endl;
			}
		}
		else //无就绪进程
		{
			cout << "无就绪进程可供调度" << endl;
		}
	}
	else
	{
		cout << "进入进程调度错误" << endl;
	}
}

/*最大优先级的就绪进程调度到运行进程*/
void getBigPriorityProcess()
{
	int max = -100;
	PCB* test = ReadyTask;
	while (test != NULL)
	{
		if (max < test->priority)
		{
			max = test->priority;
		}
		test = test->next;
	}
	if (max == ReadyTask->priority)     //判断是否为队首
	{
		RunningTask = ReadyTask;
		RunningTask->state = 0;
		ReadyTask = ReadyTask->next;
		RunningTask->next = NULL;
		RunningTask->sliceTime = 5;
	}
	else
	{
		test = ReadyTask;
		while (test->next != NULL)
		{
			if (test->next->priority == max)
			{
				RunningTask = test->next;
				RunningTask->state = 0;
				test->next = test->next->next;
				RunningTask->next = NULL;
				RunningTask->sliceTime = 5;
			}
			break;
		}
	}
}

/*显示所有进程状态*/
void showProcess()
{
	cout << endl << "***********************************创建进程*************************************" << endl;
	if (CreateTask != NULL)
	{
		printProcess(CreateTask);
	}
	cout << endl << "***********************************运行进程*************************************" << endl;
	if (RunningTask != NULL)
	{
		printProcess(RunningTask);
	}
	cout << endl << "***********************************就绪进程*************************************" << endl;
	if (ReadyTask != NULL)
	{
		printProcess(ReadyTask);
	}
	cout << endl << "***********************************阻塞进程*************************************" << endl;
	if (BlockTask != NULL)
	{
		printProcess(BlockTask);
	}
}

/*显示单个进程状态*/
void printProcess(PCB* test)
{
	cout << endl << "     进程名     优先级     需要时间     已用时间     剩余时间片     进程状态" << endl;
	while (test != NULL)
	{
		cout << "        " << test->id;
		cout << "          " << test->priority;
		cout << "           " << test->needTime;
		cout << "           " << test->arrivedTime;
		cout << "             " << test->sliceTime;
		cout << "             " << test->state;
		cout << endl;
		test = test->next;
	}
}

运行结果测试

(1)初始界面
在这里插入图片描述
(2)创建进程
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

进程1所需内存无法得到满足,无法进入就绪队列,只能处于创建状态。
在这里插入图片描述

进程2内存得到分配,进入就绪队列。由于进程2进入就绪队列时,运行队列为空,进程2被调度到运行队列中。随后进程3、4内存得到分配后进入就绪队列,等待进程调度

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(3)阻塞进程
输入选择2后,运行进程被阻塞,该进程转变为阻塞状态并进入阻塞队列。此时运行队列为空,进行进程调度,就绪队列中优先级最大的进程转变为运行状态并进入运行队列。
在这里插入图片描述

(4)唤醒进程
输入选择3后,阻塞队列中优先级最大的进程转变为就绪状态并进入就绪队列。
在这里插入图片描述

(5)撤销进程
输入选择4后,要选择撤销哪个队列中的进程。
在这里插入图片描述
选择后会循环显示队列中的进程信息。
在这里插入图片描述
(6)进程运行
在这里插入图片描述
进程3运行完毕需要时间大于初始时间片5。当时间片用完,它的优先级降低,转变为就绪状态并进入就绪队列,其余就绪进程的优先级提高,随后进行进程调度。
在这里插入图片描述
所有进程运行完毕。
在这里插入图片描述
(7)退出
在这里插入图片描述

Logo

鸿蒙生态一站式服务平台。

更多推荐