简介
在本次实验中,你将使用 C++ 实现先来先服务(First Come First Serve, FCFS)调度算法。FCFS 是最简单的 CPU 调度算法,它按照进程请求 CPU 的顺序为其分配 CPU。就绪队列中最先到达的进程将最先得到服务。
该算法易于理解和实现,但在平均等待时间方面可能无法提供最优性能。在本次实验结束时,你将了解 FCFS 算法的工作原理,并能够计算进程的重要指标,如等待时间和周转时间。
在本次实验中,你将使用 C++ 实现先来先服务(First Come First Serve, FCFS)调度算法。FCFS 是最简单的 CPU 调度算法,它按照进程请求 CPU 的顺序为其分配 CPU。就绪队列中最先到达的进程将最先得到服务。
该算法易于理解和实现,但在平均等待时间方面可能无法提供最优性能。在本次实验结束时,你将了解 FCFS 算法的工作原理,并能够计算进程的重要指标,如等待时间和周转时间。
先来先服务(First Come First Serve, FCFS)是一种非抢占式调度算法,进程按照它们进入就绪队列的顺序依次执行。在这一步中,你将创建程序文件并搭建基本结构。
首先,创建一个新的 C++ 文件:
fcfs.cpp
,然后按回车键。现在,为程序添加必要的头文件和命名空间声明:
#include <iostream>
#include <iomanip> // For formatted output
using namespace std;
int main() {
cout << "FCFS Scheduling Algorithm Implementation" << endl;
cout << "----------------------------------------" << endl;
return 0;
}
这段代码为程序搭建了基本结构,包含:
#include <iostream>
—— 用于输入/输出操作#include <iomanip>
—— 用于格式化输出表格using namespace std;
—— 使用标准命名空间main()
函数,用于显示标题编译并运行程序,确保一切设置正确:
g++ fcfs.cpp -o fcfs
./fcfs
你应该会看到以下输出:
FCFS Scheduling Algorithm Implementation
----------------------------------------
这表明程序的基本结构已正确运行。下一步,你将实现输入进程详细信息的功能。
在这一步中,你将实现收集待调度进程信息的功能。对于 FCFS 调度算法,你需要了解以下信息:
修改 fcfs.cpp
文件以包含此功能:
#include <iostream>
#include <iomanip> // For formatted output
using namespace std;
int main() {
cout << "FCFS Scheduling Algorithm Implementation" << endl;
cout << "----------------------------------------" << endl;
// Variables declaration
int n; // Number of processes
int burst_time[20]; // Array to store burst time of each process
// Get the number of processes from the user
cout << "\nEnter the number of processes (maximum 20): ";
cin >> n;
// Input validation
if (n <= 0 || n > 20) {
cout << "Invalid number of processes. Please enter a value between 1 and 20." << endl;
return 1;
}
// Get burst time for each process
cout << "\nEnter the Burst Time for each process:" << endl;
for (int i = 0; i < n; i++) {
cout << "Process P" << i + 1 << ": ";
cin >> burst_time[i];
// Input validation for burst time
if (burst_time[i] <= 0) {
cout << "Burst time must be a positive integer. Please restart the program." << endl;
return 1;
}
}
// Display the entered data
cout << "\nProcess\tBurst Time" << endl;
cout << "--------------------" << endl;
for (int i = 0; i < n; i++) {
cout << "P" << i + 1 << "\t" << burst_time[i] << endl;
}
return 0;
}
下面来看看新增的内容:
n
) 和每个进程突发时间 (burst_time[20]
) 的变量。编译并运行更新后的程序:
g++ fcfs.cpp -o fcfs
./fcfs
运行程序时,你将被提示输入进程数量及其突发时间。尝试输入以下数据:
3
5
9
4
这表示有 3 个进程,其突发时间分别为 5、9 和 4 个时间单位。你应该会看到类似以下的输出:
FCFS Scheduling Algorithm Implementation
----------------------------------------
Enter the number of processes (maximum 20): 3
Enter the Burst Time for each process:
Process P1: 5
Process P2: 9
Process P3: 4
Process Burst Time
--------------------
P1 5
P2 9
P3 4
这证实了输入功能已正确实现。下一步,你将计算每个进程的等待时间和周转时间。
在这一步中,你将为每个进程计算两个重要的指标:
下面来了解在 FCFS 算法中这些指标是如何计算的:
现在,修改 fcfs.cpp
文件以添加这些计算:
#include <iostream>
#include <iomanip> // For formatted output
using namespace std;
int main() {
cout << "FCFS Scheduling Algorithm Implementation" << endl;
cout << "----------------------------------------" << endl;
// Variables declaration
int n; // Number of processes
int burst_time[20]; // Array to store burst time of each process
int waiting_time[20]; // Array to store waiting time of each process
int turnaround_time[20]; // Array to store turnaround time of each process
int total_waiting_time = 0;
int total_turnaround_time = 0;
// Get the number of processes from the user
cout << "\nEnter the number of processes (maximum 20): ";
cin >> n;
// Input validation
if (n <= 0 || n > 20) {
cout << "Invalid number of processes. Please enter a value between 1 and 20." << endl;
return 1;
}
// Get burst time for each process
cout << "\nEnter the Burst Time for each process:" << endl;
for (int i = 0; i < n; i++) {
cout << "Process P" << i + 1 << ": ";
cin >> burst_time[i];
// Input validation for burst time
if (burst_time[i] <= 0) {
cout << "Burst time must be a positive integer. Please restart the program." << endl;
return 1;
}
}
// Calculate waiting time for each process
waiting_time[0] = 0; // First process has 0 waiting time
for (int i = 1; i < n; i++) {
waiting_time[i] = 0;
// Add burst times of all previous processes
for (int j = 0; j < i; j++) {
waiting_time[i] += burst_time[j];
}
}
// Calculate turnaround time for each process and total times
cout << "\nProcess\tBurst Time\tWaiting Time\tTurnaround Time" << endl;
cout << "----------------------------------------------------" << endl;
for (int i = 0; i < n; i++) {
turnaround_time[i] = burst_time[i] + waiting_time[i];
total_waiting_time += waiting_time[i];
total_turnaround_time += turnaround_time[i];
cout << "P" << i + 1 << "\t" << burst_time[i] << "\t\t"
<< waiting_time[i] << "\t\t" << turnaround_time[i] << endl;
}
return 0;
}
下面来看看新增的内容:
waiting_time[20]
和 turnaround_time[20]
,用于存储每个进程的等待时间和周转时间。编译并运行更新后的程序:
g++ fcfs.cpp -o fcfs
./fcfs
尝试输入与之前相同的数据:
3
5
9
4
你应该会看到类似以下的输出:
FCFS Scheduling Algorithm Implementation
----------------------------------------
Enter the number of processes (maximum 20): 3
Enter the Burst Time for each process:
Process P1: 5
Process P2: 9
Process P3: 4
Process Burst Time Waiting Time Turnaround Time
----------------------------------------------------
P1 5 0 5
P2 9 5 14
P3 4 14 18
下面来分析这些结果:
这证实了等待时间和周转时间的计算是正确的。下一步,你将计算平均时间并显示最终结果。
在这最后一步,你将计算所有进程的平均等待时间和平均周转时间。这些平均值是评估调度算法效率的重要指标。
修改 fcfs.cpp
文件以添加这些计算并完成程序:
#include <iostream>
#include <iomanip> // For formatted output
using namespace std;
int main() {
cout << "FCFS Scheduling Algorithm Implementation" << endl;
cout << "----------------------------------------" << endl;
// Variables declaration
int n; // Number of processes
int burst_time[20]; // Array to store burst time of each process
int waiting_time[20]; // Array to store waiting time of each process
int turnaround_time[20]; // Array to store turnaround time of each process
int total_waiting_time = 0;
int total_turnaround_time = 0;
float avg_waiting_time = 0.0;
float avg_turnaround_time = 0.0;
// Get the number of processes from the user
cout << "\nEnter the number of processes (maximum 20): ";
cin >> n;
// Input validation
if (n <= 0 || n > 20) {
cout << "Invalid number of processes. Please enter a value between 1 and 20." << endl;
return 1;
}
// Get burst time for each process
cout << "\nEnter the Burst Time for each process:" << endl;
for (int i = 0; i < n; i++) {
cout << "Process P" << i + 1 << ": ";
cin >> burst_time[i];
// Input validation for burst time
if (burst_time[i] <= 0) {
cout << "Burst time must be a positive integer. Please restart the program." << endl;
return 1;
}
}
// Calculate waiting time for each process
waiting_time[0] = 0; // First process has 0 waiting time
for (int i = 1; i < n; i++) {
waiting_time[i] = 0;
// Add burst times of all previous processes
for (int j = 0; j < i; j++) {
waiting_time[i] += burst_time[j];
}
}
// Calculate turnaround time for each process and total times
cout << "\nProcess\tBurst Time\tWaiting Time\tTurnaround Time" << endl;
cout << "----------------------------------------------------" << endl;
for (int i = 0; i < n; i++) {
turnaround_time[i] = burst_time[i] + waiting_time[i];
total_waiting_time += waiting_time[i];
total_turnaround_time += turnaround_time[i];
cout << "P" << i + 1 << "\t" << burst_time[i] << "\t\t"
<< waiting_time[i] << "\t\t" << turnaround_time[i] << endl;
}
// Calculate average waiting time and average turnaround time
avg_waiting_time = (float)total_waiting_time / n;
avg_turnaround_time = (float)total_turnaround_time / n;
// Display the results with two decimal places
cout << fixed << setprecision(2);
cout << "\nAverage Waiting Time: " << avg_waiting_time << " time units" << endl;
cout << "Average Turnaround Time: " << avg_turnaround_time << " time units" << endl;
// Visual representation of the FCFS schedule (Gantt chart in text)
cout << "\nGantt Chart:" << endl;
cout << " ";
for (int i = 0; i < n; i++) {
for (int j = 0; j < burst_time[i]; j++) {
cout << "--";
}
}
cout << endl << "|";
for (int i = 0; i < n; i++) {
for (int j = 0; j < burst_time[i] - 1; j++) {
cout << " ";
}
cout << "P" << i + 1;
for (int j = 0; j < burst_time[i] - 1; j++) {
cout << " ";
}
cout << "|";
}
cout << endl << " ";
for (int i = 0; i < n; i++) {
for (int j = 0; j < burst_time[i]; j++) {
cout << "--";
}
}
cout << endl;
cout << "0";
int current_time = 0;
for (int i = 0; i < n; i++) {
current_time += burst_time[i];
for (int j = 0; j < burst_time[i] * 2 - 1; j++) {
cout << " ";
}
if (current_time < 10) cout << " ";
cout << current_time;
}
cout << endl;
return 0;
}
下面来看看新增的内容:
avg_waiting_time
和 avg_turnaround_time
,用于存储平均时间。编译并运行最终程序:
g++ fcfs.cpp -o fcfs
./fcfs
尝试输入与之前相同的数据:
3
5
9
4
你应该会看到类似以下的输出:
FCFS Scheduling Algorithm Implementation
----------------------------------------
Enter the number of processes (maximum 20): 3
Enter the Burst Time for each process:
Process P1: 5
Process P2: 9
Process P3: 4
Process Burst Time Waiting Time Turnaround Time
----------------------------------------------------
P1 5 0 5
P2 9 5 14
P3 4 14 18
Average Waiting Time: 6.33 time units
Average Turnaround Time: 12.33 time units
Gantt Chart:
--------------------
| P1 | P2 | P3 |
--------------------
0 5 14 18
查看结果:
甘特图直观地展示了进程随时间的调度情况:
至此,你已完成 FCFS 调度算法的实现。你可以尝试不同数量的进程和突发时间,看看它们如何影响平均等待时间和周转时间。
在本次实验中,你已成功使用 C++ 实现了先来先服务(First Come First Serve, FCFS)CPU 调度算法。以下是你学到的关键概念和技能:
FCFS 算法基础:理解进程如何按照到达顺序进行调度。
性能指标计算:
C++ 编程概念:
可视化技术:创建基于文本的甘特图(Gantt chart),以可视化调度时间线。
FCFS 算法易于理解和实现,但并不总是能提供最优性能。它可能会导致“护航效应”,即短进程会被长进程阻塞,从而增加平均等待时间。
本次实现为理解更复杂的调度算法(如最短作业优先(Shortest Job First, SJF)、优先级调度和轮转调度(Round Robin, RR))奠定了基础,这些算法旨在优化进程调度的不同方面。