处理机调度之FCFS

本程序旨在使大家对先来先服务的处理机调度机制有更加深入的了解,步骤如下:
1.创建PCB结构体代表对相应进程的唯一标识,内含以下数据:

进程名

要求运行时间

状态

指针

2.创建相应队列和链表

deque<PCB_STRU*>Ready_Queue; //就绪队列
deque<PCB_STRU*>Block_Queue; //阻塞队列
PCB_STRU* Ready_list = (PCB_STRU*)malloc(sizeof(PCB_STRU));   //就绪状态链表
PCB_STRU* Block_list = (PCB_STRU*)malloc(sizeof(PCB_STRU));   //阻塞状态链表

3.编写对应函数(如下)并按一定顺序调用
AddAProcessToRdyQue():新建进程,则增加一个pcb到就绪队列;
RunToFinish():运行进程,则从就绪队列头部删除一进程并投入运行,显示运行状态,并顺利结束;
RunWait():运行后堵塞,从就绪队列头部删除一进程并投入运行,显示运行1个时间单位后又堵塞,并将此进程加入到堵塞队列尾部;
Signal():唤醒进程,从堵塞队列头部将堵塞的进程加入到就绪队列尾部;

Show()显示所有进程的进程控制块PCB的信息。

注意事项:
1.所有进程的添加与运行都由控制台输入指令唯一控制(最大并发度要求为5)
2.要求运行时间——假设进程需要运行的单位时间数;
  状态——可假设有三种状态,"就绪"状态、"阻塞"状态和“结束”状态。新创建进程的初始状态都为“就绪”,用“R”表示,
  当一个进程运行结束后,它的状态为“结束”,销毁此进程 “阻塞”状态的进程用“B”表示。

  指针——用指针指出下一个进程具有相同状态的进程控制块的首地址;

代码如下:

#define MAXPROCESS  5  //最大并发度
#include <stdio.h>
#include<iostream>
#include<cstring>
#include<stdlib.h>
#include<malloc.h>
#include<deque>//双端队列
using namespace std;
typedef struct PCB
{
	char           ProcessName[20];
	int            RequireRunTime;
	char           State;

	struct		   PCB* Next_PCB;
}PCB_STRU;

deque<PCB_STRU*>Ready_Queue; //就绪队列
deque<PCB_STRU*>Block_Queue; //阻塞队列
PCB_STRU* Ready_list = (PCB_STRU*)malloc(sizeof(PCB_STRU));   //就绪状态链表
PCB_STRU* Block_list = (PCB_STRU*)malloc(sizeof(PCB_STRU));   //阻塞状态链表


PCB_STRU*r = Ready_list;//指向就绪队列的最后一个节点
PCB_STRU*b = Block_list;//指向阻塞队列的最后一个节点

int g_processCount = 0;//实时记录当前进程数

void Print_Order();
void AddAProcessToRdyQue();
void RunToFinish();
void RunWait();
void Signal();
void Show();

//命令提示
void Print_Order()
{
	std::cout << "命令提示:\n";
	std::cout << "1---->New       2---->Runfinish\n";
	std::cout << "3---->RunWait   4---->Signal\n";
	std::cout << "5---->Show      0---->CloseAll\n";
}

//新建进程放入就绪队列
void AddAProcessToRdyQue()
{
	PCB_STRU* pro = (PCB_STRU*)malloc(sizeof(PCB_STRU)); //新建节点
	std::cout << "请输入新建进程名称:";
	scanf("%s", &pro->ProcessName);
	std::cout << "请输入新建进程请求运行时间:";
	std::cin >> pro->RequireRunTime;
ERR:
	std::cout << "请输入新建进程状态:";
	std::cin >> pro->State;

	//状态检测
	if (pro->State != 'R')
	{
		std::cout << "状态错误...";
		goto ERR;
	}
	//新建节点pro进队
	Ready_Queue.push_back(pro);
	//新建节点pro插入就绪链表的尾部
	pro->Next_PCB = NULL;
	r->Next_PCB = pro;
	r = r->Next_PCB;
	g_processCount++;
}

//运行一个进程到结束
void RunToFinish()
{
	if (!Ready_Queue.empty())//就绪队列不为空
	{
		PCB_STRU* pro1 = (PCB_STRU*)malloc(sizeof(PCB_STRU));
		//取出就绪队列队首元素
		pro1 = Ready_Queue.front();

		printf("进程%s运行中...\n", pro1->ProcessName);
		_sleep(2000);
		printf("进程%s运行完成!!\n", pro1->ProcessName);

		//删除就绪队列队首元素
		Ready_Queue.pop_front();
		//删除就绪链表的链首节点
		PCB_STRU*t = Ready_list->Next_PCB;
		Ready_list->Next_PCB = t->Next_PCB;
		g_processCount--;
	}
	else
	{
		std::cout << "就绪队列为空!\n";
	}
}
//运行一个进程到阻塞
void RunWait()
{
	//就绪队列不为空
	if (!Ready_Queue.empty())
	{
		PCB_STRU* pro1 = (PCB_STRU*)malloc(sizeof(PCB_STRU));
		pro1 = Ready_Queue.front();//取出就绪队列队首元素
		Ready_list->Next_PCB = pro1->Next_PCB;

		pro1->RequireRunTime--; //时间改变
		pro1->State = 'B';		//状态改变
		if (pro1->RequireRunTime != 0)//运行一秒后未结束
		{
			std::cout << "进程" << pro1->ProcessName << "运行1个单位时间\n";
			std::cout << "进程" << pro1->ProcessName << "已进入阻塞队列!\n";
			_sleep(1000);
			Block_Queue.push_back(pro1);//进入阻塞队列

			//插入阻塞链表尾部
			pro1->Next_PCB = NULL;
			b->Next_PCB = pro1;
			b = b->Next_PCB;
		}
		else//运行一秒后结束
		{
			//删除就绪队列队首元素
			Ready_Queue.pop_front();
			//从就绪链表中删除
			PCB_STRU*t = Ready_list->Next_PCB;
			Ready_list = t->Next_PCB;
			_sleep(1000);
			std::cout << "进程" << pro1->ProcessName << "运行结束\n";
		}
	}
	else
	{
		std::cout << "就绪队列为空!\n";
	}
}

//从阻塞队列唤醒一个进程
void Signal()
{
	//阻塞队列不为空
	if (!Block_Queue.empty())
	{
		//从阻塞队列中取出队首进程
		PCB_STRU* pro1 = (PCB_STRU*)malloc(sizeof(PCB_STRU));
		pro1 = Block_Queue.front();

		//删除阻塞链表的第一个元素
		if (Block_list->Next_PCB != NULL)
		{
			PCB_STRU*t = Block_list->Next_PCB;
			Block_list->Next_PCB = t->Next_PCB;
		}
		//将pro1放入就绪队列
		Ready_Queue.push_back(pro1);
		//将pro1放入就绪链表
		pro1->Next_PCB = NULL;
		r->Next_PCB = pro1;
		r = r->Next_PCB;
		if (r != NULL)
		{
			cout << "signal操作中。。。。\n";
			_sleep(1000);
			cout << "signal操作成功!\n";
		}
		else
		{
			cout << "error\n";
		}
		//删除队首元素
		Block_Queue.pop_front();
	}
	else
	{
		cout << "阻塞队列为空!!\n";
	}
}
void Show()
{
	//输出就绪队列
	if (Ready_list->Next_PCB != NULL)
	{
		cout << "就绪状态进程:\n";
		PCB_STRU*rr = Ready_list->Next_PCB;
		cout << "名称    剩余执行时间     当前状态\n";
		while (rr != NULL)
		{
			cout << rr->ProcessName << "        " << rr->RequireRunTime 
			<< "                " << rr->State << "\n";
			rr = rr->Next_PCB;
		}
	}
	else
	{
		cout << "就绪队列为空!!\n";
	}

	//输出阻塞队列
	if (Block_list->Next_PCB != NULL)
	{
		cout << "阻塞状态进程:\n";
		cout << "名称    剩余执行时间     当前状态\n";
		PCB_STRU*bb = Block_list->Next_PCB;
		while (bb != NULL)
		{
			cout << bb->ProcessName << "        " << bb->RequireRunTime
			<< "                " << bb->State << "\n";
			bb = bb->Next_PCB;
		}
	}
	else
	{
		cout << "阻塞队列为空!!\n";
	}

}
int main(int argc, char* argv[])
{
	//初始化两链表指针域
	Ready_list->Next_PCB = NULL;
	Block_list->Next_PCB = NULL;

	int order = -1; //保存指令
	Print_Order();
	while (1)
	{

		std::cout << "请输入给定的指令(0-5):";
		std::cin >> order;
		if (order > 5 || order < 0)
		{
			std::cout << "输入不合法!!请重新输入!!\n";
			continue;
		}
		//判断是否达到最大并发度
		if (g_processCount >= MAXPROCESS)
		{
			cout << "程数进已大于"<<MAXPROCESS<<endl;
			system("pause");
			exit(0);
		}
		switch (order)
		{
		case 0:
			//释放两个队列并退出
			Ready_Queue.~deque<PCB_STRU*>();
			Block_Queue.~deque<PCB_STRU*>();
			exit(EXIT_FAILURE);
			break;
		case 1:
			AddAProcessToRdyQue();
			cout << endl;
			break;
		case 2:
			RunToFinish();
			cout << endl;
			break;
		case 3:
			RunWait();
			cout << endl;
			break;
		case 4:
			Signal();
			cout << endl;
			break;
		case 5:
			Show();
			cout << endl;
			break;
		}
		Print_Order();
	}
	system("pause");
	return 0;
}

VS2013运行如下:


猜你喜欢

转载自blog.csdn.net/abraham_1/article/details/79756055
今日推荐