过程:
1.首先要了解它的工作方式,进程都到达,那么首先考虑的是到达的时间再考虑优先级,当优先级高的肯定先执行,但是不可能出现进程还没到就执行的状况,所以代码要考虑这个点,保证进程执行是对的之后再考虑优先级。
2.保证程序执行是对的,那么对收集的数据先排序,按照到达时间排序,然后拿第一个数据先直接执行,然后记录到达的时间并且作为一个时间更新点,然后每执行一次都把这个时间更新,当有新的进程能匹配这个到达时间记录点就插进队列中,保证是个可完全执行的状态。
当优先级相同的时候这时候就要考虑短作业优先的调度了
代码块的问题:
1.代码中有个小bug,外部写遍历的时候也就是进程进行作业调度后查看情况的遍历,会无法返回集合数据的大小导致程序崩溃这个点的产生会使得代码的冗余度变大,因为只能在局部里写会让代码的复用性降低,这是个可修进的bug。
2.对于排序可以多种方式,本次实验我用到的是algorithm库里的方法,当然后续的也是用到algorithm库的,不过最好用的还是lambda表达式,简洁一行搞定。
3.中间还有个小坑要注意的是拿数据,如果用迭代器去拿数据,是没办法较好的返回数据,会出现死循环的情况,可能也是测试的时候把后续代码给关闭了导致的,所以为了方便的管理数据这里再vector容器的遍历里用at()的方法调用,能较好的返回数据,避免去考虑数据类型是否需要转化等。
#include<iostream>
#include<string>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
typedef struct pcb {
string pName;//进程名
int priorityNumber;//优先数
int arriveTime;//到达时间
float needTime;//估计服务时间
float runTime;//已运行时间
string state;//进程状态 W等待 R运行 D结束
friend bool operator<(pcb a, pcb b) {
if (a.priorityNumber == b.priorityNumber)
return a.needTime > b.needTime; //时间小的优先
return a.priorityNumber < b.priorityNumber;//权值大的优先
}
}PCB;
vector<PCB> waitList;//就绪队列
priority_queue<PCB> runList;//运行队列
int n;//进程个数
//可以做一个序列的优化 保证前一个的到达时间小于后一个的到达时间。
bool myComparePCB(PCB& A, PCB& B) {
return A.arriveTime < B.arriveTime;
}
void init_pcb()//初始化pcb,输入进程信息
{
std::cout << "请输入进程的个数:";
cin >> n;
PCB r;//临时工作结点
for (int i = 0; i < n; i++) {
cout << "请输入第" << i + 1 << "个进程的名字:";
cin >> r.pName;
cout << "请输入它的优先级:";
cin >> r.priorityNumber;
cout << "请输入它的到达时间:";
cin >> r.arriveTime;
cout << "请输入它需要服务的时间:";
cin >> r.needTime;
r.runTime = 0;
r.state = "等待中";
waitList.push_back(r);
}
//进行一个排序优化,防止录入的数据不是按顺序的
sort(waitList.begin(), waitList.end(), myComparePCB);
cout << endl;
}
void showProcess(vector<PCB> waitList) //显示进程信息
{
PCB s;//临时工作结点
cout << "进程名\t|优先数 |到达时间 |服务时间 |已运行时间|状态" << endl;
for (vector<PCB>::iterator it = waitList.begin(); it != waitList.end(); it++) {
cout << it->pName << "\t|" << it->priorityNumber << "\t|" << it->arriveTime << "\t |" << it->needTime << "\t |" << it->runTime << "\t |" << it->state << endl;
}
cout << endl;
}
void runProcess(priority_queue<PCB>& runList) {//运行进程
PCB s;
int tempTime = 0;
PCB temp;
PCB indexTemp;
vector<PCB>tempList;
//先跑第一个数据:
s = waitList.front();//先在就绪队列中拿到一个然后放入运行队列中
cout << "第一个进程:" << s.pName << endl;
waitList.erase(waitList.begin());
//先更新一下时间
tempTime = s.arriveTime;
cout << "正在运行的进程" << endl;
cout << "进程名\t|优先数 |到达时间 |服务时间 |已运行时间|" << endl;//输出当前进程
cout << s.pName << "\t|" << s.priorityNumber << "\t|" << s.arriveTime << "\t |" << s.needTime << "\t |" << s.runTime << "\t |" << endl;
s.priorityNumber--;//优先数-1
s.runTime++;//已运行时间+1
s.needTime--;//还需要时间-1
//tempTime++;
runList.push(s);
//找找是否有新的PCB进来了
while (runList.size() != 0) {
//拿到需要的数据
for (int i = 0; i < waitList.size(); i++) {
temp = waitList.at(i);
if (temp.arriveTime == tempTime) {
runList.push(temp);
break;
}
}
s = runList.top();//先在就绪队列中拿到一个然后放入运行队列中
runList.pop();
//先更新一下时间
cout << "------------------------------------------------------------------" << endl;
cout << "正在运行的进程" << endl;
cout << "进程名\t|优先数 |到达时间 |服务时间 |已运行时间|" << endl;//输出当前进程
cout << s.pName << "\t|" << s.priorityNumber << "\t|" << s.arriveTime << "\t |" << s.needTime << "\t |" << s.runTime << "\t |" << endl;
s.priorityNumber--;//优先数-1
s.needTime--;//还需要时间-1
s.runTime++;//已运行时间+1
tempTime++;
//因为它属于先判定 所以会导致数据少显示一次;
if (s.needTime == -1) {
s.state = "进程已完成";
cout << "已完成进程" << "---------------------------------------->" << s.pName << endl << endl;
}
else
runList.push(s);
if (runList.empty()) {
cout << "\n所有进程运行完毕!" << endl;
return;
}
cout << "进程" << s.pName << "执行一次之后就绪队列中的进程" << endl;
//因为外部写出现爆炸的情况所以直接这里扫描数据就好了
priority_queue<PCB>tempList;
tempList = runList;
cout << "进程名\t|优先数 |到达时间 |服务时间 |已运行时间|" << endl;//输出当前进程
while (tempList.size() != 0) {
indexTemp = tempList.top();
cout << indexTemp.pName << "\t|" << indexTemp.priorityNumber << "\t|" << indexTemp.arriveTime << "\t |" << indexTemp.needTime << "\t |" << indexTemp.runTime << "\t |" << endl;
tempList.pop();
}
}
cout << endl;
}
int main() {
init_pcb();
showProcess(waitList);
cout << "----------------------------------------------------------------------" << endl;
runProcess(runList);
system("pause");
return 0;
}
借鉴了这位博主的模板:https://blog.csdn.net/BinBinCome/article/details/128124587