需求分析
进程控制块PCB的信息:
- 进程名ID ----进程标示数
- 优先数Priority,----优先数越大优先权越高
- 到达时间 arrivalTime----进程的到达时间为进程输入的时间
- 进程还需要运行时间----AllTime
- 已用CPU时间----CPUTim
- 进程的阻塞时间StartBlock----表示当进程在运行StartBlock个时间片后,进程将进入阻塞状态
- 进程的阻塞时间StartTime----表示当进程阻塞StartTime个时间片后,进程将进入就绪状态
- 进程状态----State 有Ready Waiting Running Block
- 队列指针----Next,用来将PCB排成队列
代码:
- 公共数据结构和函数
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<string>
#include<ctime>
#include<sstream>
#include<fstream>
using namespace std;
const int BLOCK_NUM = 3; // 运行BLOCK_NUM 后 阻塞
const int START_NUM = 3; // 阻塞后经历 START_NUM 时间片后,唤醒
const int ADD_PRIORITY = 1; // 增加的优先级
const int SUB_PRIORITY = 3; // 减去的优先级
const int TIME_LIMIT = 1; // 时间片
double TIME = 0; // 程序运行的时间轴
ofstream fout;
int SEEK = 0;
class PCB {
public:
string ID; // 进程名
int priority; // 进程优先级
string state; // 进程状态
double arrivalTime; //到达时间
double allTime; // 进程还需运行的时间
double CPUTime; // 已经运行的时间
double startBlock; // 进程运行StartBlock时间片后,将进入阻塞状态
double startTime; // 进程阻塞startTIme时间片后, 进入就绪状态
double totalTime; // 运行的总时间
int blockCount; // 记录阻塞次数
int wakeupCount; // 记录唤醒次数
PCB* next; // 指向下一个的指针
friend istream& operator>>(istream& is, PCB& pcb);
friend ostream& operator<<(ostream& os, const PCB& pcb);
PCB() {
this->state = "";
this->CPUTime = 0;
this->startTime = 0;
this->startBlock = 0;
this->wakeupCount = 0;
this->blockCount = 0;
this->next = NULL;
}
PCB(string _ID, int _priority, double _arrivalTime, double _allTime) :
ID(_ID), priority(_priority), arrivalTime(_arrivalTime), allTime(_allTime) {
this->state = "";
this->CPUTime = 0;
this->startTime = 0;
this->startBlock = 0;
this->wakeupCount = 0;
this->blockCount = 0;
this->next = NULL;
this->totalTime = this->allTime;
}
};
// 重载流提取运算符
ostream& operator<<(ostream& os, const PCB& pcb) {
os << " 进程名: " << pcb.ID << ", 优先级: " << pcb.priority
<< ", 到达时间: " << pcb.arrivalTime << ", 进程状态: "
<< pcb.state << ", 已经运行的时间: " << pcb.CPUTime << ", 还需运行的时间: " << pcb.allTime
<< ", 运行的总时间: " << pcb.totalTime
<< ", startTime: " << pcb.startTime << ", startBlock: "
<< pcb.startBlock << endl
<< "\t" << " 阻塞次数: " << pcb.blockCount
<< ", 唤醒次数: " << pcb.wakeupCount << endl;
return os;
}
int getRandInt(int m, int n, int seek); // 获取 [m, n)范围内的随机整数
istream& operator>>(istream& is, PCB& pcb) {
// 功能 优先级 20 - 50;
// 到达时间 1 - 100 之间到达
// 运行时间 4 - 50
int start_priority = 20;
int end_priority = 50;
int start_arrivalTime = 1;
int end_arrivalTime = 10;
int start_runTime = 5;
int end_runTime = 10;
// cout << "\t输入进程的名字: " << endl << "\t";
fout << "\t输入进程的名字: " << endl << "\t";
// cin >> pcb.ID;
// ID的输入
stringstream ss;
ss << "__" << SEEK + 1 << "__";
pcb.ID = ss.str();
fout << pcb.ID << endl;
// cout << "\t输入进程优先级: " << endl << "\t";
fout << "\t输入进程优先级: " << endl << "\t";
// cin >> pcb.priority;
pcb.priority = getRandInt(start_priority, end_priority, SEEK);
fout << pcb.priority << endl;
// cout << "\t输入进程到达的时间: " << endl << "\t";
fout << "\t输入进程到达的时间: " << endl << "\t";
// cin >> pcb.arrivalTime;
pcb.arrivalTime = getRandInt(start_arrivalTime, end_arrivalTime, SEEK);
fout << pcb.arrivalTime << endl;
// cout << "\t输入进程运行的总时间: " << endl << "\t";
fout << "\t输入进程运行的总时间: " << endl << "\t";
// cin >> pcb.allTime;
pcb.allTime = getRandInt(start_runTime, end_runTime, SEEK);
pcb.totalTime = pcb.allTime;
fout << pcb.allTime << endl;
return is;
}
// 状态链表
PCB* running = NULL; // 正在运行的PCB, 规定只有一个
PCB* blocking = NULL; //
PCB* ready = NULL; // 按照优先级进行排序的队列
PCB* finish = NULL;
PCB* waiting = NULL; // 按照到达时间进行排序的队列
//==================================================
// 公共函数
void insertPCBToWaitingByarrivalTime(PCB* p); //输入时, 按照到达时间进行排序, 加入到waiting 队列中
void insertFromWaitingToReady(void (*func)(PCB *p)); // 将满足到达的进程根据不同的要求插入到Ready队列中
void inputPCB(); // 输入PCB的信息
void displayPCB(string s); // 展示PCB的状态 s 可以传入窗台
void displayPCBOfWaiting();
void displayPCBOfBlock();
void displayFinishPCB(); // PCB完成的时候, 输出PCB
void destroyPCB(); // 程序完成后, 从running队列中 退出
string getFileName(string algoName); // 根据系统的时间获取文件的
int getRandInt(int m, int n, int seek) {
// 产生 m <= num < n的随机数
// 随机数种子
srand((unsigned)time(NULL) * seek);
// 模除加加法计算 [m, n) 的随机整数
int randint = rand() % (n - m) + m;
return randint;
}
void displayPCBOfWaiting() {
PCB* pW = waiting;
cout << endl;
fout << endl;
cout << "\t\t---------------------正在等待的PCB: -------------------" << endl;
fout << "\t\t---------------------正在等待的PCB: -------------------" << endl;
while (pW != NULL) {
cout << *pW << endl;
fout << *pW << endl;
pW = pW->next;
}
// cout << "\t\t---------------------正在等待的PCB: -------------------" << endl;
cout << "\t\t====================================================" << endl;
cout << endl;
fout << endl;
}
void displayPCBOfBlock() {
PCB* pB = blocking;
cout << endl;
fout << endl;
cout << "\t\t---------------------已被阻塞的PCB: -------------------" << endl;
fout << "\t\t---------------------已被阻塞的PCB: -------------------" << endl;
while (pB != NULL) {
cout << *pB << endl;
fout << *pB << endl;
pB = pB->next;
}
cout << endl;
fout << endl;
}
string getFileName(string algoName) {
// 获取时间 time_t是一个64位的整型。记录的是从1970-01-01 00:00:00到现在经过的时间,精度只能到秒
time_t now = time(0);
struct tm t;
localtime_s(&t, &now);
// 将信息输出到字符串流
stringstream ss;
ss << algoName << "LogFile" << t.tm_year + 1900 << "." << t.tm_mon + 1 << "." <<
t.tm_mday << "_" << t.tm_hour << "." << t.tm_min << "." << t.tm_sec << ".txt";
cout << "写入的文件为: " << ss.str() << endl;
return ss.str();
}
// 通过到达时间进行 插入到等到序列进行排序
void insertPCBToWaitingByarrivalTime(PCB* p) {
/**
* 按照到达时间的优先级进行排序,到达时间在前的进行在前
*
*/
// 设置状态
p->state = "Waiting";
PCB* p1, * p2;
bool insert = false;
// 如果 等待队列 为空,或者小于第一个的到达时间,插入到等待队列的第一个
if (waiting == NULL || p->arrivalTime < waiting->arrivalTime) {
p->next = waiting;
waiting = p;
}
// 到达时间比第一个大, 在第一个的后面 查找
else {
p1 = waiting;
p2 = p1->next;
while (p2 != NULL) {
if (p->arrivalTime < p2->arrivalTime) {
// 在两个中间, 插入到第一个和第二个的中间
p->next = p2;
p1->next = p;
p2 = NULL; // 说明已经找到位置
insert = true;
}
else {
// 指针向下移动
p1 = p1->next;
p2 = p2->next;
}
}
if (insert == false) {
// 此时说明没有只有头部节点,只能插入到它的后面 此时 p2 == NULL
p1->next = p;
}
}
}
// 将满足到达的进程根据不同的要求插入到Ready队列中
void insertFromWaitingToReady(void (*func)(PCB *p)) {
PCB* p;
if (waiting != NULL) {
// 当开始的第一个到达时间满足的时候
while (waiting != NULL && waiting->arrivalTime <= TIME) {
p = waiting;
// cout << "进程: " << p->ID << "insertP" << "时间满足条件" << (p->arrivalTime <= time) << endl;
p->state = "Ready";
waiting = waiting->next;
func(p);
}
if (waiting != NULL) {
// 第一个条件不能满足的时候
PCB* p1 = waiting;
PCB* p2 = p1->next;
while (p1 != NULL && p2 != NULL) {
if (p2->arrivalTime <= TIME) {
// 修改状态
PCB* insert_p = p2;
insert_p->state = "Ready";
// 移动指针
if (p2->next != NULL) {
p1->next = p2->next;
p2 = p1->next;
insert_p->next = NULL;
func(insert_p);
}
else {
// p2刚好是最后满足条件的
p1->next = NULL; // 释放连接
p2->next = NULL;
func(p2);
break;
}
}
else {
// 向下移动
p1 = p1->next;
p2 = p2->next;
}
}
}
}
}
// 输入信息
void inputPCB() {
// 手动输入进程
/**
* 输入数据到链表中
* 按照一定的格式输入
*/
cout << "\t\t输入进程的数目: " << endl << "\t\t";
fout << "\t\t输入进程的数目: " << endl << "\t\t";
int NUM;
cin >> NUM;
fout << NUM << endl;
for (int i = 0; i < NUM; ++i) {
SEEK = i;
// cout << "\t输入第" << i + 1 << "个进程" << endl;
PCB* p = new PCB();
cin >> *p;
// fout << *p;
insertPCBToWaitingByarrivalTime(p);
}
// 随机产生进程
}
// 每一步都展示PCB信息
void displayPCB(string s) {
cout << endl;
cout << endl;
fout << endl;
fout << endl;
cout << "\t\t---------------------------" << s << "--------------------------" << endl;
fout << "\t\t---------------------------" << s << "--------------------------" << endl;
PCB* pR = ready, * pRun = running, * pB = blocking, * pW = waiting;
// 输出正在运行的队列
cout << "\t\t====================================================" << endl;
fout << "\t\t====================================================" << endl;
cout << endl;
fout << endl;
cout << "\t\t---------------------正在运行的PCB: -------------------" << endl;
fout << "\t\t---------------------正在运行的PCB: -------------------" << endl;
while (pRun != NULL) {
cout << *pRun << endl;
fout << *pRun << endl;
pRun = pRun->next;
}
// cout << "\t\t---------------------正在运行的PCB: -------------------" << endl;
// 输出ready
cout << "\t\t---------------------已经就绪的PCB: -------------------" << endl;
fout << "\t\t---------------------已经就绪的PCB: -------------------" << endl;
while (pR != NULL) {
cout << *pR << endl;
fout << *pR << endl;
pR = pR->next;
}
// cout << "\t\t---------------------已经就绪的PCB: -------------------" << endl;
// 输出阻塞队列
cout << "\t\t---------------------已被阻塞的PCB: -------------------" << endl;
fout << "\t\t---------------------已被阻塞的PCB: -------------------" << endl;
while (pB != NULL) {
cout << *pB << endl;
fout << *pB << endl;
pB = pB->next;
}
// cout << "\t\t---------------------已被阻塞的PCB: -------------------" << endl;
cout << "\t\t---------------------正在等待的PCB: -------------------" << endl;
fout << "\t\t---------------------正在等待的PCB: -------------------" << endl;
while (pW != NULL) {
cout << *pW << endl;
fout << *pW << endl;
pW = pW->next;
}
// cout << "\t\t---------------------正在等待的PCB: -------------------" << endl;
// cout << "\t\t====================================================" << endl;
// cout << "\t\t---------------------------" << s << "--------------------------" << endl;
// fout << "\t\t---------------------------" << s << "--------------------------" << endl;
cout << endl;
cout << endl;
fout << endl;
fout << endl;
}
// 只有完成的时候才进行展示完成的PCB信息
void displayFinishPCB() {
PCB* p = finish;
cout << "\t---------------finish------------" << endl;
fout << "\t---------------finish------------" << endl;
while (p != NULL) {
cout << *p << endl;
fout << *p << endl;
p = p->next;
}
cout << "\t---------------finish------------" << endl;
fout << "\t---------------finish------------" << endl;
}
// 进程完成
void destroyPCB() {
/**
* 将完成的PCB插入到队列首
*/
if (running != NULL) {
cout << "\t\t******* " << running->ID << " 运行完成 ****" << endl << endl;
fout << "\t\t******* " << running->ID << " 运行完成 ****" << endl << endl;
running->state = "Finish";
// 前插入到完成队列
running->next = finish;
finish = running;
// 运行队列置空
running = NULL;
// 展示已经完成的 PCB
// displayFinishPCB();
}
}
动态最大优先数优先的调度算法
调度原则:
- 进程的优先数及需要的运行时间可以事先人为地指定,进程的到达时间为进程输入的时间
- 进程的运行时间以时间片为单位进行计算
- 进程在就绪队列中带一个时间片,优先数加1
- 每个进程的状态可以是就绪R(Ready)、运行N(Run)、阻塞B(Block)、或完成F(Finish)四种状态之一
- 就绪进程获得CPU后都只能运行一个时间片,用已占用CPU时间加1来表示
- 如果运行一个时间片后,进程的已占用CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减3,然后把它插入就绪队列等待CPU
- 每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的PCB,以便进行检查
- 重复以上过程,直到所要进程都完成为止
// ===============动态优先级调度算法===============
void insertAndSortPCBToReadyByPriorityOFDP(PCB* p); // 按照优先级的先后插入到ready队列
void runPCBOfDP(); // 从 ready 中取出 PCB 运行
void wakeupPCBByPriorityOfDP(); // 唤醒进程,以优先级插入到ready
void DP(); // 处理函数
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<动态优先级调度 <<<<<<<<<<<<<<<<<<<<<<<<<<
// 通过优先级插入
void insertAndSortPCBToReadyByPriorityOFDP(PCB* p) {
/**
* 排序插入PCB队列
* 1. 比链表的第一个大的时候,或者首队列是空队列,此时 新PCB 插入到队列首
* 2. 如果 新PCB 的在链表的中间,则使用两个指针进行移动
* 3. 注意插入的时候,如果只有一个节点且优先级最高,则直接插入到它的后面,用没有插入 insert进行标记
*/
PCB* first, * second;
bool insert = false; // 是否插入
// 如果就绪队列为空,或者优先级高于队列首元素,则插入到队列首
if ((ready == NULL) || (p->priority > ready->priority)) {
p->next = ready;
ready = p;
}
// 要插入的PCB 优先级 比首PCB小的时候
else {
first = ready;
second = first->next;
// 循环插入到两个进程之间
while (second != NULL) {
// 如果在第一个和第二个之间
if (p->priority >= second->priority) {
p->next = second;
first->next = p;
second = NULL;
insert = true;
}
else {
first = first->next;
second = second->next;
}
}
// 表示没有插入到first与second之间
// 此时直接插入到第一个的后面, 说明说明链表的头部只有一个节点,且优先级高
if (!insert) {
first->next = p;
p->next = NULL;
}
}
}
// 运行处理进程函数
void runPCBOfDP() {
/**
* 步骤:
* 1. 每一次从不为空的 ready 队列中 取出第一个作为处理进程
* 2. 当有进程可以处理的时候,工作时间加 1 个时间片,优先级 加 固定的优先级
1). 当达到完成时间的时候,进程退出
2). 当使用一定的时间片后,进程自己阻塞
3). 都没有满足的时候,再次插入到就绪队列
无论是退出、阻塞、再次就绪, running 都设置为空
*/
// 如果没有运行的进程,从就绪进程中选取
if (running == NULL) {
if (ready != NULL) {
// 取出第一个进程
running = ready;
ready = ready->next;
running->state = "Running";
running->next = NULL;
// 就绪队列前进
}
}
bool runningFlag = false;
if (running != NULL) {
runningFlag = true;
// 进程运行的时间增加
running->CPUTime++;
// 进程优先级加1
running->allTime--;
running->priority += ADD_PRIORITY;
// 展示运行的状态
displayPCB("运行......");
if (running->allTime <= 0) {
destroyPCB();
}
else {
// 进程运行要阻塞的时间 加 1
running->startBlock += TIME_LIMIT;
if (running->startBlock >= BLOCK_NUM) {
// 修改状态, 插入到队列首,无需排序
running->state = "Block";
running->startBlock = 0;
running->blockCount++;
// 加入到block队列的头部
running->next = blocking;
blocking = running;
running = NULL;
}
else {
// 优先级降低
running->priority -= SUB_PRIORITY;
// 修改状态
running->state = "Ready";
PCB* p = running;
p->next = NULL;
insertAndSortPCBToReadyByPriorityOFDP(p);
// 将running进程插入到就绪队列后,running队列为空
running = NULL;
}
}
}
if (!runningFlag && waiting != NULL) {
displayPCBOfWaiting();
}
if (!runningFlag && blocking != NULL) {
// 当有队列被阻塞的时候,进行唤醒
displayPCBOfBlock();
}
wakeupPCBByPriorityOfDP(); // 每次唤醒
}
void wakeupPCBByPriorityOfDP() {
/**
* 唤醒的步骤
* 1. 当blocking队列不为空的时候进行唤醒
* 2. 检查链表首节点是否都满足,满足则插入到就绪队列
* 3. 当第一个节点不满足的时候,检查第二个节点,保留前一个,用链表遍历的思想
*/
if (blocking != NULL) {
PCB* p = blocking;
while (p != NULL) {
p->startTime++;
p = p->next;
}
// 如何唤醒阻塞的进程
/**
* 第一个进程全部满足条件 能被唤醒
*/
while (blocking != NULL && blocking->startTime >= START_NUM) {
p = blocking;
blocking = blocking->next;
p->startTime = 0;
p->wakeupCount++;
// 最后修改指针
p->next = NULL;
insertAndSortPCBToReadyByPriorityOFDP(p);
}
/**
* 不是第一个的 唤醒
*/
if (blocking != NULL) {
PCB* p1 = blocking;
PCB* p2 = p1->next;
while (p2 != NULL && p1 != NULL) {
if (p2->startTime >= START_NUM) {
PCB* i_p = p2;
i_p->startTime = 0;
i_p->wakeupCount++;
// 移动指针
p1->next = p2->next;
p2 = p1->next;
insertAndSortPCBToReadyByPriorityOFDP(i_p);
}
else {
p1 = p1->next;
p2 = p2->next;
}
}
}
}
}
void DP() {
string t = getFileName("DB_algo_");
fout.open(t.c_str());
char c;
inputPCB();
displayPCB("输入的PCB");
cout << endl << endl;
fout << endl << endl;
while (ready != NULL || running != NULL || blocking != NULL || waiting != NULL) {
TIME += 1;
cout << "\t\t运行的时间 : " << TIME << endl;
fout << "\t\t运行的时间 : " << TIME << endl;
// c = getchar();
insertFromWaitingToReady(insertAndSortPCBToReadyByPriorityOFDP);
runPCBOfDP();
}
displayPCB("最后信息");
displayFinishPCB();
fout.close();
}
先来先服务算法
// 先来先服务调度算法
void insertAndSortToReadyByArrivalTimeOfFCFS(PCB* p); // 插入到ready队列 按照到达时间进行排序
void runPCBOfFCFS(); // 从ready中取出一个处理
void FCFS(); // 主处理函数
// >>>>>>>>>>>>>>>>>>>>>>>先来先服务算法<<<<<<<<<<<<<<<<<<<<<<<
// 按照先到时间的优先级插入
void insertAndSortToReadyByArrivalTimeOfFCFS(PCB* p) {
// 将到达时间的进程放到ready的后面
if (ready == NULL) {
ready = p;
ready->next = NULL;
}
else {
PCB* pT = ready;
while (pT->next != NULL) {
pT = pT->next;
}
pT->next = p;
p->next = NULL;
}
}
// 先来先服务算法
void runPCBOfFCFS() {
/**
* 第一个到达的先服务,服务完毕后结束
*/
if (running == NULL) {
if (ready != NULL) {
running = ready;
ready = ready->next;
running->state = "Running";
running->next = NULL;
}
}
bool runningFlag = false;
if (running != NULL) {
runningFlag = true;
running->CPUTime++;
running->allTime--;
displayPCB("Running");
if (running->allTime <= 0) {
destroyPCB();
}
}
if (!runningFlag && waiting != NULL) {
displayPCBOfWaiting();
}
}
// 算法主体
void FCFS() {
// char c;
string t = getFileName("FCFS_algo_");
fout.open(t.c_str());
inputPCB();
displayPCB("输入的PCB");
cout << endl << endl;
fout << endl << endl;
while (ready != NULL || running != NULL || blocking != NULL || waiting != NULL) {
TIME += 1;
cout << "\t\t运行的时间 : " << TIME << endl;
fout << "\t\t运行的时间 : " << TIME << endl;
// c = getchar();
insertFromWaitingToReady(insertAndSortToReadyByArrivalTimeOfFCFS);
runPCBOfFCFS();
}
displayPCB("最后信息");
displayFinishPCB();
fout.close();
}
短进程优先算法
// 短进程优先
void insertAndSortToReadyByMinAllTimeOfSPF(PCB* p); // 插入到ready队列 按照总运行时间最低
void runPCBOfSPF(); // 从 ready 中取出PCB进行处理
void SPF();
// >>>>>>>>>>>>>>>>>>>>>>>>>> 短进程优先算法 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>
// 到达时间后插入到ready时进行 按总运行大小 排序
void insertAndSortToReadyByMinAllTimeOfSPF(PCB* p) {
PCB* p1, * p2;
bool insert;
// 第一个ready PCB为空的时候, 或者是 更短的进程, 插入前面
if ((ready == NULL) || (p->allTime <= ready->allTime)) {
p->next = ready;
ready = p;
}
else {
// 说明没有插入到第一个, 在第一个与第二个之间查找
p1 = ready;
p2 = p1->next;
insert = false;
while (p2 != NULL) {
if (p->allTime <= p2->allTime) {
// 此时插入到p1 与 p2 之间
p1->next = p;
p->next = p2;
// p2 = NULL; // 已经插入,结束的条件
insert = true;
break;
}
else {
p1 = p1->next;
p2 = p2->next;
}
}
if (!insert) {
// 此时小于第一个 没有第二个, 插入第一个的后面
ready->next = p;
p->next = NULL;
}
}
}
void runPCBOfSPF() {
// 取出ready的第一个PCB,已经排好序的 最短进程
if (running == NULL) {
if (ready != NULL) {
running = ready;
ready = ready->next;
running->state = "Running";
running->next = NULL;
}
}
bool runningFlag = false;
if (running != NULL) {
runningFlag = true;
// 对于正在运行的进程进行处理
running->CPUTime++;
running->allTime--;
displayPCB("Running");
//
if (running->allTime <= 0) {
destroyPCB();
}
}
if (!runningFlag && waiting != NULL) {
displayPCBOfWaiting();
}
}
void SPF() {
// 输入之前打开文件
string t = getFileName("SPF_algo_");
fout.open(t.c_str());
inputPCB();
displayPCB("输入的PCB");
cout << endl << endl;
fout << endl << endl;
while (ready != NULL || running != NULL || blocking != NULL || waiting != NULL) {
TIME += 1;
cout << "\t\t运行的时间 : " << TIME << endl;
fout << "\t\t运行的时间 : " << TIME << endl;
insertFromWaitingToReady(insertAndSortToReadyByMinAllTimeOfSPF);
runPCBOfSPF();
}
displayPCB("最后信息");
displayFinishPCB();
fout.close();
}
时间片轮转调度算法
// >>>>>>>>>>>>>>>>>>>>>>>>>> 时间片轮转调度算法 >>>>>>>>>>>>>>>>>>
// 插入原则 按进程到达的顺序进行
void insertAndSortToReadyByFCFSOfTimeLimit(PCB* p) {
// 将到达时间的进程放到ready的后面
if (ready == NULL) {
ready = p;
ready->next = NULL;
}
else {
PCB* pT = ready;
while (pT->next != NULL) {
pT = pT->next;
}
pT->next = p;
p->next = NULL;
}
}
void wakeupPCBByFCFSOfTimeLimit() {
/**
* 唤醒的步骤
* 1. 当blocking队列不为空的时候进行唤醒
* 2. 检查链表首节点是否都满足,满足则插入到就绪队列
* 3. 当第一个节点不满足的时候,检查第二个节点,保留前一个,用链表遍历的思想
*/
if (blocking != NULL) {
PCB* p = blocking;
while (p != NULL) {
p->startTime++;
p = p->next;
}
// 如何唤醒阻塞的进程
/**
* 第一个进程全部满足条件 能被唤醒
*/
while (blocking != NULL && blocking->startTime >= START_NUM) {
p = blocking;
blocking = blocking->next;
p->startTime = 0;
p->wakeupCount++; // 唤醒次数加一
insertAndSortToReadyByFCFSOfTimeLimit(p);
}
/**
* 第一个进程不能唤醒的时候, 唤醒后面的进程
*/
if (blocking != NULL) {
PCB* p1 = blocking;
PCB* p2 = p1->next;
while (p2 != NULL && p1 != NULL) {
if (p2->startTime >= START_NUM) {
p2->startTime = 0;
p1->next = p2->next;
p2->wakeupCount++;
insertAndSortToReadyByFCFSOfTimeLimit(p2);
p2 = p1->next; // p2指向下一个, 以便于循环继续
}
else {
p1 = p1->next;
p2 = p2->next;
}
}
}
}
}
void runPCBOfTimeLimit() {
// 取出第一个进程进行处理
if (running == NULL) {
if (ready != NULL) {
running = ready;
ready = ready->next;
running->state = "Running";
running->next = NULL; // 只有一个进程在处理机
}
}
bool runningFlag = false;
if (running != NULL) {
runningFlag = true;
running->CPUTime++;
running->allTime--;
displayPCB("TimeLimit Running");
if (running->allTime <= 0) {
destroyPCB(); // 结束 running的进程
}
else {
running->startBlock += TIME_LIMIT;
if (running->startBlock >= BLOCK_NUM) {
// 修改状态
running->state = "Block";
running->blockCount++;
running->startBlock = 0;
// 插入到队列的首
running->next = blocking;
blocking = running;
running = NULL; // 删除运行的进程
}
}
}
if (!runningFlag && waiting != NULL) {
displayPCBOfWaiting();
}
if (!runningFlag && blocking != NULL) {
// 当有队列被阻塞的时候,进行唤醒
displayPCBOfBlock();
wakeupPCBByFCFSOfTimeLimit();
}
}
void TimeLimit() {
char c;
// 输入之前打开文件
string t = getFileName("TimeLimit_algo_");
fout.open(t.c_str());
inputPCB();
displayPCB("输入的PCB");
cout << endl << endl;
fout << endl << endl;
while (ready != NULL || running != NULL || blocking != NULL || waiting != NULL) {
TIME += 1;
cout << "\t\t运行的时间 : " << TIME << endl;
fout << "\t\t运行的时间 : " << TIME << endl;
// c = getchar();
insertFromWaitingToReady(insertAndSortToReadyByFCFSOfTimeLimit);
runPCBOfTimeLimit();
}
displayPCB("最后信息");
displayFinishPCB();
fout.close();
}
执行
int main() {
// DP();
// FCFS();
// SPF();
TimeLimit();
return 0;
}