编写c++的一个可视化的进程调度算法演示程序
时间: 2024-04-29 20:22:24 浏览: 122
C++实现进程调度的算法
5星 · 资源好评率100%
以下是一个简单的可视化的进程调度算法演示程序的C++实现,使用了Qt库进行界面开发:
```cpp
#include <QtWidgets/QApplication>
#include <QtWidgets/QMainWindow>
#include <QtCharts/QChartView>
#include <QtCharts/QBarSet>
#include <QtCharts/QBarSeries>
#include <QtCharts/QValueAxis>
#include <QtCharts/QBarCategoryAxis>
#include <QtCharts/QStackedBarSeries>
#include <QtCharts/QChart>
#include <QtCore/QObject>
#include <QtCore/QTimer>
#include <QtCore/QDebug>
#include <vector>
QT_CHARTS_USE_NAMESPACE
class Process
{
public:
Process(int id, int arrival_time, int burst_time)
: id_(id),
arrival_time_(arrival_time),
burst_time_(burst_time),
remaining_time_(burst_time),
waiting_time_(0),
is_done_(false)
{}
int id() const { return id_; }
int arrival_time() const { return arrival_time_; }
int burst_time() const { return burst_time_; }
int remaining_time() const { return remaining_time_; }
int waiting_time() const { return waiting_time_; }
bool is_done() const { return is_done_; }
void set_remaining_time(int remaining_time) { remaining_time_ = remaining_time; }
void set_waiting_time(int waiting_time) { waiting_time_ = waiting_time; }
void mark_as_done() { is_done_ = true; }
private:
int id_;
int arrival_time_;
int burst_time_;
int remaining_time_;
int waiting_time_;
bool is_done_;
};
class Scheduler : public QObject
{
Q_OBJECT
public:
Scheduler(std::vector<Process> processes, int time_quantum, QObject *parent = nullptr)
: QObject(parent),
processes_(processes),
time_quantum_(time_quantum),
current_time_(0),
current_process_(-1),
is_done_(false)
{}
void run();
int total_waiting_time() const;
bool is_done() const { return is_done_; }
signals:
void process_started(int process_id, int start_time);
void process_finished(int process_id, int finish_time);
private:
std::vector<Process> processes_;
int time_quantum_;
int current_time_;
int current_process_;
bool is_done_;
};
void Scheduler::run()
{
Q_ASSERT(processes_.size() > 0);
while (!is_done_)
{
// Check if all processes are done
bool all_done = true;
for (const Process& process : processes_)
{
if (!process.is_done())
{
all_done = false;
break;
}
}
if (all_done)
{
is_done_ = true;
break;
}
// Check if we need to switch to a new process
if (current_process_ == -1 || processes_[current_process_].remaining_time() == 0)
{
// Find the next process that has arrived and hasn't finished yet
int next_process = -1;
for (size_t i = 0; i < processes_.size(); ++i)
{
if (!processes_[i].is_done() && processes_[i].arrival_time() <= current_time_)
{
next_process = i;
break;
}
}
if (next_process == -1)
{
// No processes ready to run, just advance time
++current_time_;
continue;
}
else
{
// Switch to the new process
current_process_ = next_process;
emit process_started(processes_[current_process_].id(), current_time_);
}
}
// Run the current process for the time quantum
int remaining_time = processes_[current_process_].remaining_time();
int run_time = std::min(time_quantum_, remaining_time);
current_time_ += run_time;
processes_[current_process_].set_remaining_time(remaining_time - run_time);
// Check if the current process has finished
if (processes_[current_process_].remaining_time() == 0)
{
processes_[current_process_].mark_as_done();
processes_[current_process_].set_waiting_time(current_time_ - processes_[current_process_].arrival_time() - processes_[current_process_].burst_time());
emit process_finished(processes_[current_process_].id(), current_time_);
current_process_ = -1;
}
}
}
int Scheduler::total_waiting_time() const
{
int total_waiting_time = 0;
for (const Process& process : processes_)
{
total_waiting_time += process.waiting_time();
}
return total_waiting_time;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
private slots:
void start_simulation();
void update_chart(int process_id, int start_time, int finish_time);
private:
void setup_chart();
std::vector<Process> processes_;
int time_quantum_;
QChartView *chart_view_;
QStackedBarSeries *series_;
QValueAxis *axis_x_;
QBarCategoryAxis *axis_y_;
};
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent),
chart_view_(nullptr),
series_(nullptr),
axis_x_(nullptr),
axis_y_(nullptr)
{
// Define the processes
processes_.push_back(Process(1, 0, 10));
processes_.push_back(Process(2, 1, 5));
processes_.push_back(Process(3, 2, 3));
processes_.push_back(Process(4, 3, 4));
processes_.push_back(Process(5, 4, 2));
// Define the time quantum
time_quantum_ = 2;
// Set up the chart
setup_chart();
// Set up the main window
setCentralWidget(chart_view_);
setWindowTitle(tr("Process Scheduler"));
}
void MainWindow::setup_chart()
{
// Create the series
series_ = new QStackedBarSeries();
// Add the data
for (const Process& process : processes_)
{
QBarSet *bar_set = new QBarSet(QString("Process %1").arg(process.id()));
bar_set->append(process.burst_time());
series_->append(bar_set);
}
// Create the chart and add the series
QChart *chart = new QChart();
chart->addSeries(series_);
// Set the axes
axis_x_ = new QValueAxis();
axis_x_->setRange(0, 20);
axis_x_->setLabelFormat("%d");
chart->addAxis(axis_x_, Qt::AlignBottom);
axis_y_ = new QBarCategoryAxis();
QStringList categories;
for (const Process& process : processes_)
{
categories << QString("Process %1").arg(process.id());
}
axis_y_->append(categories);
chart->addAxis(axis_y_, Qt::AlignLeft);
// Connect the signals
connect(this, &MainWindow::update_chart, this, &MainWindow::update_chart);
connect(chart, &QChart::plotAreaChanged, [=](const QRectF& rect) {
qreal x_scale = axis_x_->length() / (axis_x_->max() - axis_x_->min());
qreal y_scale = axis_y_->length() / (axis_y_->categories().size() + 1);
chart->scroll(-rect.x() / x_scale, 0);
});
// Set up the chart view
chart_view_ = new QChartView(chart);
chart_view_->setRenderHint(QPainter::Antialiasing);
}
void MainWindow::start_simulation()
{
// Create the scheduler
Scheduler *scheduler = new Scheduler(processes_, time_quantum_, this);
// Connect the signals
connect(scheduler, &Scheduler::process_started, this, &MainWindow::update_chart);
connect(scheduler, &Scheduler::process_finished, this, &MainWindow::update_chart);
// Run the scheduler
scheduler->run();
// Show the total waiting time
int total_waiting_time = scheduler->total_waiting_time();
QMessageBox::information(this, tr("Process Scheduler"), tr("Total waiting time: %1").arg(total_waiting_time));
// Clean up
delete scheduler;
}
void MainWindow::update_chart(int process_id, int start_time, int finish_time)
{
QStringList categories = axis_y_->categories();
int index = categories.indexOf(QString("Process %1").arg(process_id));
QBarSet *bar_set = series_->barSets()[index];
bar_set->replace(0, finish_time - start_time);
series_->setBarWidth(0.8);
series_->setStackingGap(0);
QPalette palette;
QColor color = palette.color(QPalette::Active, QPalette::Highlight);
bar_set->setColor(color);
if (finish_time == start_time)
{
bar_set->setColor(Qt::gray);
}
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
#include "main.moc"
```
该程序的界面包含一个水平条形图,每个条形表示一个进程的执行时间。程序使用了Qt Charts库来创建和更新条形图。在调度程序运行时,每当一个进程开始执行或结束执行时,都会发出一个信号来更新条形图。最后,程序显示总等待时间的消息框。
阅读全文