代码
#include <iostream>
#include <queue>
#include <set>
#include <fstream>
using namespace std;
enum type{arrival, finish};
struct event
{
int time;
type t;
string procNo;
int remainServT;
bool firstArv;//到达事件是否为第一次
};
int main()
{
auto cmp = [](event l, event r){return l.time < r.time;};
multiset<event, decltype(cmp)> q(cmp);//按时间顺序排列的事件队列
auto cmp2 = [](event l, event r){return l.remainServT > r.remainServT;};
priority_queue<event, vector<event>, decltype(cmp2)> waitingProc(cmp2);//按剩余处理时间排列的阻塞进程队列
//初始化事件队列
ifstream in("data.txt");
int procCnt;
in >> procCnt;
char No;
int arrivalT, serviceT;
event temp;
temp.t = arrival;
for(int i = 0; i < procCnt; ++i)
{
in >> No >> arrivalT >> serviceT;
temp.time = arrivalT;
temp.procNo = No;
temp.remainServT = serviceT;
temp.firstArv = true;
q.insert(temp);
}
bool cpuWorking = false;
event workingProc;//正在运行的进程
int sysTime = 0;
while(!q.empty())
{
event p = *q.begin();
q.erase(q.begin());
sysTime = p.time;
if(p.t == arrival)//到达事件
{
int workingRemain = workingProc.time+workingProc.remainServT-sysTime;//当前进程的剩余时间
bool wait = p.remainServT >= workingRemain;
//workingRemain==0意味着当前进程已结束,但同时另一进程的到达事件在队列中先于此进程的结束事件,会引起错误,下为处理
if(cpuWorking && wait && workingRemain==0)
{
waitingProc.push(p);
continue;
}
else if(cpuWorking && wait)//等待
{
cout << sysTime << " : " + p.procNo + " arrive\n";
event newWait = p;
newWait.time = workingProc.time+workingProc.remainServT;
newWait.firstArv = false;
waitingProc.push(newWait);
}
else//抢占
{
if(cpuWorking)//处理被抢占的进程
{
cout << sysTime << " : " + workingProc.procNo + " pause\n";
//删除原来的结束事件
auto it=q.begin();
while(it->t != finish)
it++;
q.erase(it);
//新的到达事件
event newWait = workingProc;
newWait.remainServT -= sysTime-workingProc.time;
newWait.firstArv = false;
waitingProc.push(newWait);
}
//运行此进程
cpuWorking = true;
workingProc = p;
if(p.firstArv)
cout << sysTime << " : " + p.procNo + " arrive\n";
cout << sysTime << " : " + p.procNo + " running\n";
event f;
f.time = p.time + p.remainServT;
f.t = finish;
f.procNo = p.procNo;
q.insert(f);
}
}
else//结束事件
{
cout << sysTime << " : " + p.procNo + " finish\n";
if(!waitingProc.empty())
{
event select = waitingProc.top();
waitingProc.pop();
workingProc = select;
if(select.firstArv)
cout << sysTime << " : " + select.procNo + " arrive\n";
cout << sysTime << " : " + select.procNo + " running\n";
event f;
f.time = sysTime + select.remainServT;
f.t = finish;
f.procNo = select.procNo;
q.insert(f);
}
}
}
return 0;
}
测试数据
data.txt
5
A 0 3
B 2 6
C 4 4
D 6 5
E 8 2
网友评论