操作系统实验 进程调度算法

操作系统实验 进程调度算法

1.Dev 5.6.1 版本 C++ 代码

2.visual studio 2015 C++ 代码

3.实验要求如图


1.Dev5.6.1 进程调度算法

//为了方便阅读,我把所有东西都写在了一个文件里。 
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<stdbool.h>

static int aPCBID=1024;
/*
** PCB 结构体。 
*/ 
typedef struct PCB
{
	int PCBID;
	unsigned int mode;// 1 代表 优先级法。 2 代表  时间片法。 3 代表没模式。 
	int Pri;//优先级
	int NeedCPUTime;//所需 CPU 的时间。
	bool IsFinish;// true 代表已经完成。
	
	int NeedSlice;//总计需要的时间片数量。 
	int NowCPUSlice;//当前已占用的时间片数 
	int ContinueCPUSlice;//每次运行连续的时间片数。 
}PCB;

/*
**链表节点的结构体 
*/ 
typedef struct Node
{
	PCB data;
	Node* next;
}Node;

void PrintNodeList(Node *head);
/*
**创建链表头节点。
**头节点不保存数据。
**返回 头节点首地址。 
*/ 
Node* newLinkList()
{
	Node* NewList=(Node *)malloc(sizeof(Node));
	NewList->data.mode=3;
	NewList->data.IsFinish=0;
	NewList->next=NULL;
	return NewList;
}

/*
**将 PCB 拷贝进 NewNode; 
*/
void CopyPCBToNode(Node *NewNode,PCB *a)
{
	NewNode->data.PCBID=a->PCBID;
	NewNode->data.mode=a->mode;
	NewNode->data.Pri=a->Pri;
	NewNode->data.NeedCPUTime=a->NeedCPUTime;
	NewNode->data.IsFinish=a->IsFinish;
	NewNode->data.NeedSlice=a->NeedSlice;
	NewNode->data.NowCPUSlice=a->NowCPUSlice;
	NewNode->data.ContinueCPUSlice=a->ContinueCPUSlice;
}

/*
**在 pos 个位置插入节点。
**第一个存数据的地方 pos=1; 
*/
bool InsertPCBToPos(int pos,PCB *a,Node *head)
{
	Node* NewNode=(Node *)malloc(sizeof(Node));
	if(NewNode==NULL)
	{
		throw "InsertPCBToPos() wrong!\n";
		return false;
	}
	CopyPCBToNode(NewNode,a);
	
	Node* temp=head;
	for(int i=1;i<pos;i++)//移动指针到要插入的地方。 
	{
		temp=temp->next;
	}
	NewNode->next=temp->next;
	temp->next=NewNode;
	
	return true;
}


/*
**打印所有节点。 
*/
void PrintNodeList(Node *head)
{
	
	Node* temp=head->next;
	while(temp!=NULL)
	{
		if(temp->data.mode==1)
		{
			printf("ID:%d\tPri=%8d\tNeedCPUTime=%8d\tIsFinish=%6d\n",temp->data.PCBID,temp->data.Pri,temp->data.NeedCPUTime,temp->data.IsFinish);
		}
		else if(temp->data.mode==2)
		{
			printf("ID:%d\tNeedSlice=%8d\tContinueCPUSlice=%8d\tIsFinish=%6d\n",\
			temp->data.PCBID,temp->data.NeedSlice,temp->data.ContinueCPUSlice,temp->data.IsFinish);
		}
		else
		{
			printf("PrintNodeList() something get int to trouble!\n");
			break;
		}
		temp=temp->next;
	}
	printf("\n");
}

/*
**释放所有节点。 
*/
void FreeAllNode(Node *head)
{
	Node *temp=head;
	Node *del=temp;
	while(temp!=NULL)
	{
		del=temp;
		temp=temp->next;
		free(del);
	}
}

/*
**释放 第 pos 个节点.
**头节点是第 0 个。 
*/
void FreePosNode(Node *head,int pos)
{
	Node *temp=head;
	if(pos==0)
	{
		FreeAllNode(head);
	}
	for(int i=1;i<pos;i++)
	{
		temp=temp->next;
	}
	Node *del=temp->next;
	temp->next=del->next;
	free(del);
}

/*
**优先权模拟法函数。
**生成 num 个 进程。用随机数初始化。
**这里把优先权 限制在 18-30;
**把所需时间 限制在 8-30;
**把 num 个进程 排序后,不断运行。 
*/
void YOUXIANJI(int num)
{
	Node* head=newLinkList();//分配头节点。 
	if(head==NULL)// 是否抛出异常。 
	{
		throw "YOUXIANJI() wrong!";
		return ;
	}
	
	head->data.mode=3;
	head->data.Pri=999999999;//头节点为最大优先级,比较方便后来插入。 
	Node* temp;//用于下面的查找。 
	int pos;
	PCB WaitInsert; 
	WaitInsert.mode=1;
	 
	//不断插入新节点。 
	for(int i=0;i<num;i++)
	{
		Node *NewNode=(Node*)malloc(sizeof(Node));
		if(NewNode==NULL)
		{
			throw "YOUXIANJI() wrong!";
			return ;
		}
		temp=head;
		
		WaitInsert.Pri=rand()%13+18;
		WaitInsert.NeedCPUTime=rand()%23+8;
		WaitInsert.PCBID=aPCBID++;
		WaitInsert.IsFinish=0;
		pos=0;
		//寻找合适的插入位置。 
		while(temp!=NULL)
		{
			if(WaitInsert.Pri>temp->data.Pri)
			{
				break ;
			}
			else
			{
				pos++;
			}
			temp=temp->next;
		} 
		InsertPCBToPos(pos,&WaitInsert,head);
	}
	printf("inital processes queue:\n");
	PrintNodeList(head);
	printf("\n");
	
	PCB tPCB;//临时使用的PCB 变量。 
	tPCB.mode=1;tPCB.IsFinish=0;
	
	while(num>=0)
	{
		temp=head->next;
		printf("运行前优先级队列:\n");
		PrintNodeList(head);
		temp->data.NeedCPUTime=temp->data.NeedCPUTime-1;
		temp->data.Pri=temp->data.Pri-3;
		
		if(temp->data.NeedCPUTime<=0)
		{
			temp->data.IsFinish=1; 
			printf("运行之后:\n");
			PrintNodeList(head);
			
			Node *del=temp;
			temp=temp->next;
			head->next=temp;
			free(del);
			num--;
		}
		
		
		{
			printf("运行之后:\n");
			PrintNodeList(head);
			if(temp==NULL)
			{
				break ;
			}
			tPCB.NeedCPUTime=temp->data.NeedCPUTime;
			tPCB.Pri=temp->data.Pri;
			tPCB.IsFinish=temp->data.IsFinish;
			tPCB.PCBID=temp->data.PCBID;
			FreePosNode(head,1);
			
			Node *ttemp=head;
			pos=0;
			while(ttemp!=NULL)
			{
				if(ttemp->data.Pri<tPCB.Pri)
				{
					break;
				}
				else
				{
					pos++;
				}
			
				ttemp=ttemp->next;
			}
			InsertPCBToPos(pos,&tPCB,head);
			
		}
		
		
		
	}
	printf("优先权模拟结束\n");
	FreeAllNode(head);
}

/*
**轮转法模拟。
**输入 n 模拟 n 个进程 的轮转法。
**总计所需 CPU 时间限制 在 18-30 
**进程 CPU 连续使用时间 限制在 1-3; 
*/
void LUNZHUAN(int num)
{
	Node* head=newLinkList();//分配头节点。 
	if(head==NULL)// 是否抛出异常。 
	{
		throw "LUNZHUAN() wrong!";
		return ;
	}
 
	head->data.mode=3;
	PCB WaitInsert;
	WaitInsert.mode=2;
	 
	//不断插入新节点。 
	for(int i=0;i<num;i++)
	{
		Node *NewNode=(Node*)malloc(sizeof(Node));
		if(NewNode==NULL)
		{
			throw "LUNZHUAN() wrong!";
			return ;
		}
		WaitInsert.NeedSlice=rand()%13+18;
		WaitInsert.NowCPUSlice=0;
		WaitInsert.PCBID=aPCBID++;
		WaitInsert.IsFinish=0;
		WaitInsert.ContinueCPUSlice=rand()%3+1;
		//寻找合适的插入位置。 
		
		InsertPCBToPos(i+1,&WaitInsert,head);
	}
	printf("inital processes queue:\n");
	PrintNodeList(head);
	printf("\n");
				
	Node* temp;
	while(num>0)
	{
		temp=head->next;
		while(temp->data.NowCPUSlice<temp->data.ContinueCPUSlice)
		{
			temp->data.NowCPUSlice++;
			temp->data.NeedSlice--;
			if(temp->data.NeedSlice<=0)
			{
				temp->data.IsFinish=1;
				PrintNodeList(head);
				break;
			}
		}
		temp->data.NowCPUSlice=0;
		PCB tPCB;
		tPCB.mode=temp->data.mode;
		tPCB.PCBID=temp->data.PCBID;
		tPCB.NeedSlice=temp->data.NeedSlice;
		tPCB.NowCPUSlice=temp->data.NowCPUSlice;
		tPCB.ContinueCPUSlice=temp->data.ContinueCPUSlice;
		tPCB.IsFinish=temp->data.IsFinish;
		FreePosNode(head,1);
		if(temp->data.NeedSlice<=0)
		{
			num--;
		}
		else
		{
			InsertPCBToPos(num,&tPCB,head);
		}
		PrintNodeList(head);
		
	}
}
int main()
{
	loop:
	int n;
	printf("输入进程总数:\n"); 
	scanf("%d",&n);
	if(n>=6||n<=2)
	{
		printf("建议输入 2 - 6 个 进程。重新输入。\n");
		goto loop; 
	} 
	printf("选择调度方法: 1.有限区,2.轮转法\n");
	int FangFa;
	scanf("%d",&FangFa);
	srand(time(NULL));
	
	switch(FangFa)
	{
		case 1:
			{
				YOUXIANJI(n);
				break;
			}
		case 2:
			{
				LUNZHUAN(n);
				break;
			}
		default :
			{
				break; 
			} 
	}
	return 0;
}

Visual Studio 2015 版本

主函数

 //**********************************************************************
//主函数:
// JinChengDiaoDu.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include"PCB.h"
#include<iostream>
#include "DuiLie.cpp"
using namespace std;
int PCB::sum = 1024;
int main()
{
	
	int n;
	std::cout<< "输入进程数量:_______\b\b\b\b\b\b\b";
	std::cin>> n;
	char ch;
	std::cout<< "输入模式(A/B):_______\b\b\b\b\b\b\b";
	//cin >> ch;
	std::cin>> ch;
	
	while (ch != 'Q')
	{
		DuiLie<PCB> queA;
		PCB::sum = 1024;
		switch (ch)
		{
		case 'A':
		case 'a':
		{
			std::cout<< "模式 A(优先权法) 模拟" << endl;
			PCB x;
			x.PrintA();
			for (int i = 0; i < n; i++)
			{
				PCB a(queA.randxy(0,100),queA.randxy(1,30));
				queA.getIn(a);
			}
			queA.print();
			//queA.simulationA();
			queA.showA(n);
			break;
		}
		case 'B':
		case 'b':
		{
			std::cout<<"模式 B(时间片轮转法) 模拟" << endl;
			PCB x;
			x.PrintB();
			for (int i = 0; i < n; i++)
			{

				PCB a(queA.randxy(0,3), queA.randxy(1, 30),0);
				queA.getIn(a);
				
			}
			queA.print();
			queA.simulationB();
			break;
		}
			
		default :

			std::cout<< "只有模式 A 和 B" << endl;
		}
		
		std::cout<< "输入进程数量:_______\b\b\b\b\b\b\b";
		std::cin>> n;
		std::cout<< "Q 结束  " << "输入模式(A/B):_______\b\b\b\b\b\b\b";
		std::cin>> ch;
		
	}
	
	getchar();
	getchar();
    return 0;
}

DuiLie类 .h 文件

//***********************************************************************************
//队列类头文件:
#pragma once
#include<cstdio>
#include<ctime>
#include<cstdlib>
#include<iostream>
using namespace std;
template<typename T>
class DuiLie;

template<typename T>
class DuiLie
{
public:
	DuiLie();
	DuiLie(T a[], int len);
	~DuiLie();
private:
	int head;
	int tail;
	T data[500];

public:
	int randxy(int x,int y);//生成随机数
	bool isEmpty();//队列空则为 1
	bool isFull();
	T getIn(T a);
	T popOut();
	void Tsort();//按照优先权排序
	void print();
	void simulationA();
	void simulationB();
	void insert(T a,int pos);
	void showA(int n);
	void showB();
};

DuiLie类 CPP文件

//**********************************************************************
//队列类cpp:
#include "stdafx.h"
#include "DuiLie.h"

template<typename T>
DuiLie<T>::DuiLie()
{
	srand(time(NULL));
	head = tail = 0;
}

template<typename T>
DuiLie<T>::DuiLie(T a[], int len)
{
	srand(time(NULL));
	head = 0;
	tail = len ;
	for (int i = 0; i < len; i++)
	{
		data[i] = a[i];
	}
}

template<typename T>
DuiLie<T>::~DuiLie()
{
	cout << "模拟结束" << endl;
}

template<typename T>
int DuiLie<T>::randxy(int x, int y)
{
	int res = rand()%(y-x)+1;
	res += x;
	return res;
}

template<typename T>
bool DuiLie<T>::isEmpty()
{
	if (head >= tail)
	{
		return true;
	}
	else
	{
		return false;
	}
	
}

template<typename T>
bool DuiLie<T>::isFull()
{
	if (tail > 500)
	{
		return true;
	}
	return false;
}

template<typename T>
T DuiLie<T>::getIn(T a)
{
	data[tail] = a;
	tail++;
	return a;
}

template<typename T>
T DuiLie<T>::popOut()
{
	T a = this->data[head];
	head++;
	return a;
}

template<typename T>
void DuiLie<T>::Tsort()
{
	for (int i = head; i < tail-1; i++)
	{
		for (int j = head+1; j < tail - i+head; j++)
		{
			if (data[j-1] < data[j])
			{
				T b = data[j];
				data[j] = data[j - 1];
				data[j - 1] = b;
			}
		}
	}
}

template<typename T>
void DuiLie<T>::print()
{
	for (int i = head; i < tail; i++)
	{
		cout << data[i];
	}
	cout << endl;
}

template<typename T>
void DuiLie<T>::simulationA()
{
	if (isFull())
	{
		std::cout << "队列太满" << endl;
		return;
	}
	int x = 0;
	this->Tsort();
	cout << "初始化排队后:" << endl;
	this->print();

	while (!isEmpty())
	{
		x++;
		this->data[head].UpPriority(-3);
		this->data[head].UpNeedTime(-1);
		this->data[head].UpRunTime(1);
		cout << "第" << x << "秒" << endl;
		
		if (data[head].getNeedTime() <= 0)
		{
			data[head].setFinish(true);
		}
		this->print();
		//PCB temp=this->popOut();
		this->Tsort();
		if(data[head].getNeedTime()<=0)
		{
			this->popOut();
		}
	}
}

template<typename T>
void DuiLie<T>::simulationB()
{
	while (!isEmpty())
	{
		data[head].UpNeedSlice(-1);
		data[head].UpRunSlice(1);
		
		bool m = false;
		if (data[head].getNeedSlice() <= 0)
		{
			data[head].setFinish(true);
			this->print();
			this->popOut();
			m = true;
			if (isEmpty())
			{
				return;
			}
		}
		else
		{
			this->print();
			if (m==false)
			{
				if (data[head].getRunSlice() >= data[head].getTimeSlice())
				{
					data[head].setRunSlice(0);
					PCB temp = this->popOut();
					this->getIn(temp);
				}
				else
				{

				}
			}
			else
			{

			}
		}
		

	}
}

template<typename T>
void DuiLie<T>::insert(T a, int pos)
{
	for (int i = tail - 1; a>data[i]; i--)
	{
		data[i] = data[i - 1];
	}
}

template<typename T>
void DuiLie<T>::showA(int n)
{
	this->Tsort();
	cout << "初始化排队后:" << endl;
	this->print();
	printf("运行顺序:\n");
	if (isFull())
	{
		std::cout << "队列太满,终止程序" << endl;
		return;
	}
	int x = 0;
	
	while (!isEmpty())
	{
		x++;
		this->data[head].UpPriority(-3);
		this->data[head].UpNeedTime(-1);
		this->data[head].UpRunTime(1);
		if (x % 8 == 0)
		{
			printf("\n");
		}
		printf("%6d", data[head].getPCBID());

		if (data[head].getNeedTime() <= 0)
		{
			data[head].setFinish(true);
		}
		//PCB temp=this->popOut();
		this->Tsort();
		if (data[head].getNeedTime() <= 0)
		{
			this->popOut();
		}
	}
	cout << endl;
}

PCB类 .h文件

//**********************************************************************
//PCB类头文件:
#pragma once
#include<iostream>
#include<ostream>
#include<iomanip>
using namespace std;

class PCB
{
public:
	PCB();
	PCB(int priority, int needTime);
	PCB(int timeSlice, int needSlice, int runSlice);
	PCB(const PCB &a);
	~PCB();
	static int sum;//用于PCBID
	
protected:

	char mode;
	bool finish;//1 为已经完成。
	int PCBID;// 
	int priority;//优先权
	int needTime;//程序所需时间
	int runTime;
	
	int needSlice;//总计需要的时间片。 
	int timeSlice;//每次运行的时间片。
	int runSlice;//已经运行的时间片数量。 
public:
	void PrintA();
	void PrintB();
	void Print_A();
	void Print_B();
	int getNeedTime();
	int getNeedSlice();
	int getRunSlice();
	int getTimeSlice();
	int getPCBID();
	void UpNeedTime(int num);
	void UpPriority(int num);
	void UpRunTime(int num);
	void setFinish(bool m);
	void setRunSlice(int n);
	void UpNeedSlice(int num);
	void UpRunSlice(int num);
	friend ostream &operator<<(ostream &os,PCB &a);
	PCB &operator=(const PCB &a);
	bool operator>(const PCB a);//比较优先权
	bool operator<(const PCB a);
	void setPCBID();
};

inline ostream &operator<<(ostream &os,PCB &a)
{
	if(a.mode == 'A' )
	{
		os<<a.PCBID<<"    "<<a.priority<<"    "<<a.needTime<<"     "<<a.runTime<<"     ";
		if(a.finish==true)
		{
			os<<"是"<<endl;
		}
		else
		{
			os<<"否 "<<endl;
		}
	}

	else
	{
		os<<a.PCBID<<"    "<<a.timeSlice<<"    "<<a.needSlice<<"     "<<a.runSlice<<"     ";
		if(a.finish==true)
		{
			os<<"是"<<endl;
		}
		else
		{
			os<<"否 "<<endl;
		}

	}
return os;
}

PCB类

//**********************************************************************

//PCB类cpp:
#include "stdafx.h"
#include "PCB.h"

PCB::PCB()
{
	sum++;
}

PCB::PCB(int priority, int needTime)
{
	this->priority = priority;
	this->needTime = needTime;
	this->runTime = 0;
	this->finish = 0;
	this->mode = 'A';
	this->setPCBID();
	sum++;
}

PCB::PCB(int timeSlice, int needSlice, int runSlice)
{
	this->timeSlice = timeSlice;
	this->needSlice = needSlice;
	this->runSlice = 0;
	this->mode = 'B';
	this->setPCBID();
	this->finish = 0;
	sum++;
}

PCB::PCB(const PCB & a)
{
	this->finish = a.finish;
	this->PCBID = a.PCBID;
	this->mode = a.mode;
	//if (a.mode == 'A')
	//{
		this->priority = a.priority;
		this->needTime = a.needTime;
		this->runTime = a.runTime;
	//}
	//else
	//{
		this->needSlice = a.needSlice;
		this->timeSlice = a.timeSlice;
		this->runSlice = a.runSlice;
	//}
}

PCB::~PCB()
{
	this->finish = 1;
}

void PCB::PrintA()
{
	cout << "进程号 " << "优先权 " << "所需时间 " << "已运行 " << "是否完成" << endl;
}

void PCB::PrintB()
{
	cout << "进程号 " << "每次时间片 " << "需要时间片 " << "已经运行时间 " << "是否完成   " << endl;
}
void PCB::Print_A()
{
	cout <<setw(20)<< PCBID << "        " << priority << "                                                                                                     " \
		<< needTime << "					                                       " << runTime << "                  ";
	if (finish == true)
	{
		cout << "是" << endl;
	}
	else
	{
		cout << "否 " << endl;
	}
}

void PCB::Print_B()
{
	cout <<setw(20)<< PCBID << "    " << timeSlice << "    " << needSlice << "     " << runSlice << "     ";
	if (finish == true)
	{
		cout << "是" << endl;
	}
	else
	{
		cout << "否 " << endl;
	}
}

int PCB::getNeedTime()
{
	return needTime;
}

int PCB::getNeedSlice()
{
	return needSlice;
}

int PCB::getRunSlice()
{
	return runSlice;
}

int PCB::getTimeSlice()
{
	return timeSlice;
}

int PCB::getPCBID()
{
	return PCBID;
}

void PCB::UpNeedTime(int num)
{
	needTime += num;
}

void PCB::UpPriority(int num)
{
	priority += num;
}

void PCB::UpRunTime(int num)
{
	runTime += num;
}

void PCB::setFinish(bool m)
{
	finish = m;
}

void PCB::setRunSlice(int n)
{
	runSlice = n;
}

void PCB::UpNeedSlice(int num)
{
	needSlice += num;
}

void PCB::UpRunSlice(int num)
{
	runSlice += num;
}

PCB & PCB::operator=(const PCB & a)
{
	this->finish = a.finish;
	this->PCBID = a.PCBID;
	this->mode = a.mode;
	//if (a.mode == 'A')
	//{
		this->priority = a.priority;
		this->needTime = a.needTime;
		this->runTime = a.runTime;
	//} 
	//else
	//{
		this->needSlice = a.needSlice;
		this->timeSlice = a.timeSlice;
		this->runSlice = a.runSlice;
	//}
	return *this;
}

bool PCB::operator>(const PCB a)
{
	if (this->priority > a.priority)
	{
		return true;
	}
	return false;
}

bool PCB::operator<(const PCB a)
{
	if (this->priority < a.priority)
	{
		return true;
	}
	return false;
}

void PCB::setPCBID()
{
	PCBID = sum;
}



猜你喜欢

转载自blog.csdn.net/wang_huizhang/article/details/80095792