- 先来先服务
- 短进程优先算法
- 优先级调度(抢占)
- 优先级调度
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
struct PCB
{
int id;
double turnaround_time;
double weighted_turnaround_time;
double wait_time;
double start_time;
double coming_time;
double service_time;
double finish_time;
int youxianji;
double run_time;
};
int n;
vector<PCB> process_list;
vector<PCB> res;
void input_process_count()
{
printf("请输入进程数量:");
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
PCB pcb;
pcb.id = i + 1;
pcb.run_time = 0;
pcb.start_time = -1;
process_list.push_back(pcb);
}
}
void input_youxianshu()
{
for (int i = 0; i < n; i++)
{
printf("请输入进程%d的优先级:", process_list[i].id);
scanf("%d", &process_list[i].youxianji);
}
}
void input_coming_time()
{
for (int i = 0; i < n; i++)
{
printf("请输入进程%d的到达时间:", process_list[i].id);
scanf("%lf", &process_list[i].coming_time);
}
}
void input_serve_time()
{
for (int i = 0; i < n; i++)
{
printf("请输入进程%d所需时间", process_list[i].id);
scanf("%lf", &process_list[i].service_time);
}
}
int choose_method()
{
int select = 0;
cout << "*****************************************\n";
cout << "1 \t 先来先服务算法 *******\n";
cout << "2 \t 短进程优先算法 *******\n";
cout << "3 \t 优先级调度(抢占) *******\n";
cout << "4 \t 优先级调度(非抢占) *******\n";
cout << "请选择: ";
cin >> select;
return select;
}
int cmpByComingTime(PCB a, PCB b)
{
return a.coming_time < b.coming_time;
}
int cmpByServiceTime(PCB a, PCB b)
{
return a.service_time > b.service_time;
}
void FCFS()
{
sort(process_list.begin(), process_list.end(), cmpByComingTime);
double time = process_list[0].coming_time;
for (int i = 0; i < n; i++)
{
PCB pcb = process_list[i];
pcb.start_time = time;
pcb.wait_time = time - pcb.coming_time;
pcb.finish_time = time + pcb.service_time;
pcb.turnaround_time = pcb.finish_time - pcb.coming_time;
pcb.weighted_turnaround_time = (pcb.turnaround_time) / pcb.service_time;
time = pcb.finish_time;
process_list[i] = pcb;
res.push_back(pcb);
}
}
void SJF()
{
int top = 0;
vector<PCB> short_jobs;
sort(process_list.begin(), process_list.end(), cmpByComingTime);
double time = process_list[0].coming_time;
while (top < n || !short_jobs.empty())
{
if (short_jobs.empty())
short_jobs.push_back(process_list[top++]);
PCB pcb = short_jobs[int(short_jobs.size() - 1)];
if (pcb.start_time == -1)
pcb.start_time = time;
pcb.wait_time = time - pcb.coming_time;
pcb.finish_time = time + pcb.service_time;
pcb.turnaround_time = pcb.finish_time - pcb.coming_time;
pcb.weighted_turnaround_time = (pcb.turnaround_time) / pcb.service_time;
time = pcb.finish_time;
res.push_back(pcb);
short_jobs.pop_back();
for (; top < n && process_list[top].coming_time < time; top++)
{
short_jobs.push_back(process_list[top]);
}
sort(short_jobs.begin(), short_jobs.end(), cmpByComingTime);
}
}
bool cmpByPriority(PCB a, PCB b)
{
if (a.youxianji == b.youxianji)
return a.coming_time > b.coming_time;
return a.youxianji < b.youxianji;
}
void PriorityNo()
{
int top = 0;
vector<PCB> priority_higher;
sort(process_list.begin(), process_list.end(), cmpByComingTime);
double time = process_list[0].coming_time;
while (top < n || !priority_higher.empty())
{
if (priority_higher.empty())
priority_higher.push_back(process_list[top++]);
PCB pcb = priority_higher[int(priority_higher.size() - 1)];
if (pcb.start_time == -1)
pcb.start_time = time;
pcb.wait_time = time - pcb.coming_time;
pcb.finish_time = time + pcb.service_time;
pcb.turnaround_time = pcb.finish_time - pcb.coming_time;
pcb.weighted_turnaround_time = (pcb.turnaround_time) / pcb.service_time;
time = pcb.finish_time;
res.push_back(pcb);
priority_higher.pop_back();
for (; top < n && process_list[top].coming_time < time; top++)
{
priority_higher.push_back(process_list[top]);
}
sort(priority_higher.begin(), priority_higher.end(), cmpByPriority);
}
}
void PriorityYes()
{
int top = 0;
vector<PCB> priority_higher;
sort(process_list.begin(), process_list.end(), cmpByComingTime);
double time = process_list[0].coming_time;
while (top < n || !priority_higher.empty())
{
if (priority_higher.empty())
priority_higher.push_back(process_list[top++]);
PCB pcb = priority_higher[int(priority_higher.size() - 1)];
if (pcb.start_time == -1)
{
pcb.start_time = time;
pcb.wait_time = pcb.start_time - pcb.coming_time;
}
if (top < n && process_list[top].coming_time <= time + pcb.service_time - pcb.run_time)
{
pcb.run_time += process_list[top].coming_time - time;
time += process_list[top].coming_time - time;
priority_higher[priority_higher.size() - 1] = pcb;
priority_higher.push_back(process_list[top++]);
sort(priority_higher.begin(), priority_higher.end(), cmpByPriority);
if (pcb.run_time == pcb.service_time)
{
pcb.finish_time = time;
pcb.turnaround_time = pcb.finish_time - pcb.coming_time;
pcb.weighted_turnaround_time = (pcb.turnaround_time) / pcb.service_time;
res.push_back(pcb);
priority_higher.pop_back();
}
}
else
{
pcb.finish_time = time + pcb.service_time - pcb.run_time;
pcb.turnaround_time = pcb.finish_time - pcb.coming_time;
pcb.weighted_turnaround_time = (pcb.turnaround_time) / pcb.service_time;
time = time + pcb.service_time - pcb.run_time;
res.push_back(pcb);
priority_higher.pop_back();
}
}
}
bool cmpById(PCB a, PCB b)
{
return a.id < b.id;
}
void print_schedulInfo()
{
printf("进程编号\t提交时间\t运行时间\t开始时间\t等待时间\t完成时间\t周转时间\t带权周转时间\n");
sort(res.begin(), res.end(), cmpById);
double start = 0x3f3f3f3f3f, end = 0;
double allTT = 0, allWTT = 0, runTime = 0;
for (int i = 0; i < n; i++)
{
PCB pcb = res[i];
start = min(start, pcb.start_time);
end = max(end, pcb.finish_time);
allTT += pcb.turnaround_time;
allWTT += pcb.weighted_turnaround_time;
runTime += pcb.service_time;
printf("%8d\t%8.2f\t%8.2f\t%8.2f\t%8.2f\t%8.2f\t%8.2f\t%8.2f\n", pcb.id, pcb.coming_time, pcb.service_time, pcb.start_time, pcb.wait_time, pcb.finish_time, pcb.turnaround_time, pcb.weighted_turnaround_time);
}
printf("平均周转时间%.2f\t平均带权周转时间%.2f\tCPU利用率%.2f\t系统吞吐量%.2f\n", allTT / n, allWTT / n, (runTime) / (end - start), (n) / (end - start));
}
int main()
{
input_process_count();
input_youxianshu();
input_coming_time();
input_serve_time();
int choose = choose_method();
switch (choose)
{
case 1:
FCFS();
break;
case 2:
SJF();
break;
case 3:
PriorityYes();
break;
default:
PriorityNo();
break;
}
print_schedulInfo();
return 0;
}