操作系统实验 进程调度算法
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;
}