提示:实验源码见最下方
一、实验目的
多道系统中,当就绪进程数大于处理机数时,须按照某种策略决定哪些进程优先占用处理机。本实验模拟实现处理机调度,加深了解处理机调度的工作过程。
二、实验内容
选择一个调度算法,实现处理机调度。
1、设计一个按优先权调度算法实现处理机调度的程序;
2、设计按时间片轮转实现处理机调度的程序。
三、实验方法
本实验程序基于Qt,实现了处理机调度算法的图形化显示。实现了优先级调度和时间片轮转调度两个算法,并且实现了自动和手动调度两个操作模式,可以直观地看到进程的调度情况。
四、实验过程
1.需求分析
(1).PCB的构建:应该建立一个PCB类,并且需要有PID,运行时间,优先级,状态,PCB指针五个属性。
(2).运行时间规定:要求为大于0的整数。
(3).队列的构建:后备队列,就绪队列,运行队列(CPU),挂起队列,终止队列。
(4).后备队列的构建:在程序打开时后备队列应该提前存好进程数据。
(5).就绪队列的道数,就绪队列规定4道。
(6).老化:如果是优先级调度算法,采用动态优先权调度,从就绪队首选进程运行: 优先权-1/要求运行时间-1 ,要求运行时间为0时,撤销该进程。
(7).如果内存中进程数少于规定道数,可自动从后备队列通过作业调度选择一作业进入,作业调度算法可自行选择。
(8).被挂起进程入挂起队列,设置解挂功能用于将指定挂起进程解挂并入就绪队列。
(9).运行过程简述:添加进程到后备队列,从后备队列中调用进程到就绪队列,并在就绪队列按优先级排序(优先级调度),选择首位上CPU,每隔一秒老化一次,若此时就绪队列上的进程优先级高于CPU上的,则抢占,要求运行时间为0时,撤销该进程到终止队列。
(10).可动态增加进程。
(11).每次调度后,显示各进程状态。
2.概要设计
(1).类的设计:
设想将本实验程序以MVC的架构进行构建,首先应该构建一个PCB类,存储PCB模型;其次应该构建一个main window类和一个add Widget类,显示整体的图形化界面和添加进程的界面;然后是中间层的管理类,PCB Controller类用来管理后台的各进程状态队列中的PCB的增删改,和队列之间的移动。之后由于要使用数据库来初始化后备队列的值,所以再加上一个Queue DAO 类来作为数据库与Controller的接口。附:后来因为打算做一个使用方法的解析,所以再加上一个using Ways类(widget)。
总计是 6 个类。
下面是部分头文件中的属性和方法的展示。
(2).功能设计:
2.1.五个队列的显示:后备队列,终止队列,挂起队列采用Q table View显示,就绪队列用四个按钮来显示,设置按钮的Text来展示就绪队列,CPU上的进程也是用按钮来显示。
2.2.动画效果:做一个简单的动画效果,开始运行后,就绪队列上的按钮先排序,然后第一个按钮飞向CPU的部分,实现按钮的移动。
2.3添加进程:可以动态的添加进程,实时显示在后备队列中。
2.4设计细节分析:
- 在程序初始化的时候,会自动从数据库调用已存在的后备队列的PCB数据,并显示出来; 2.点击开始运行按钮,程序会根据选定的自动/手动模式和调度算法类型开始进行CPU调度; 3.点击开始运行按钮后,不可以再点击,否则程序会发出警告信息,但是可以进行下一步,重新开始等其他操作; 4.在点击重新开始按钮后,程序恢复到最初始状态,此时点击开始运行按钮可以重新开始新一轮的调度;
- 在程序开始运行后,点击下一步,将正在运行的进程老化,并且如果此时有抢占的话会发生抢占事件;
6.自动模式下,将自动调用下一步无需手点;
7.当没有进程可以调用时,点击下一步,则会跳出警告,如未出现警告,将自动模式暂停即可;
8.算法切换可以在运行的过程中切换,此时会提示切换成功;
9.自动手动可以实时切换。
10.选择挂起队列中的进程的名字,点击解挂,即可解挂,解挂后的进程会被放到后备队列的头部;
11.1.添加进程不可以与现存在的进程重名,否则会警告; 添加进程的时间必须是大于零的整数,否则会警告; 进程名和时间必须都填入,否则会警告;
3.详细设计
只展示部分细节:
- .调用关系:main window 中有一个 PCB controller 的指针,有一个 add widget的指针,add widget 也有一个PCB controller 的指针,程序初始化阶段,初始化PCB controller 指针和add widget指针,并且让add widget中的PCB controller 指针指向同一个。其次,PCB controller 中的队列采用Q Vector设计,用来存储PCB,PCB controller 中也包含一个Queue DAO指针用来初始化调用数据库的内容。
- 后台队列之间的转移:
例如:后备队列到就绪队列:
五、实验代码
只展示部分实验代码:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
setWindowIcon(QIcon("Images/mainwindowIcon.png"));
UsingWays *u=new UsingWays();
u->show();
addnewprocessdialog= new AddNewProcessDialog();//设置添加进程的指针
PcbController= new AllPcbController();//设置PCB管理指针
addnewprocessdialog->setPcbControllerPointer(PcbController);//将pcbcontroller设置到dialog里
menuBar()->setVisible(false);//隐藏菜单栏
ui->mainToolBar->setVisible(false);//隐藏工具栏
setWindowTitle("CPU调度模拟");
setFixedSize(1370,930);
createAllConnect();
setFirstButton();//初始化所有按钮
//waiting队列
m_tableModel =new QStandardItemModel();
ui->waiting_tableView->setModel(m_tableModel);
//terminate队列
t_tableModel =new QStandardItemModel();
ui->terminate_tableView->setModel(t_tableModel);
//hanging队列
h_tableModel =new QStandardItemModel();
ui->hanging_tableView->setModel(h_tableModel);
showTableViewHead();
m_animation = new QPropertyAnimation();
m_animation->setTargetObject(&(FirstButton)); //设置使用动画的控件
m_animation->setEasingCurve(QEasingCurve::Linear); //设置动画效果
//自动运行
tim=new QTimer(this);
connect(tim,SIGNAL(timeout()), this,SLOT(on_Next_pushButton_clicked()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::reWaiting()
{
//此函数的作用是显示Waiting表格中的内容
/*初始化waiting队列*/
qDebug()<<"调用reWaiting第一次";
int row=0;//记录行数
int lie=0;//记录列数
m_tableModel->clear();//非常非常非常重要!!!!
m_tableModel->setHorizontalHeaderItem(0, new QStandardItem("进程名"));
m_tableModel->setHorizontalHeaderItem(1, new QStandardItem("运行时间"));
m_tableModel->setHorizontalHeaderItem(2, new QStandardItem("优先权"));
//setColumnWidth设置每一列的宽度
this->ui->waiting_tableView->setColumnWidth(0, 140); //设置列的宽度
this->ui->waiting_tableView->setColumnWidth(1, 140);
this->ui->waiting_tableView->setColumnWidth(2, 140);
/*设置行字段名*/
m_tableModel->setRowCount(100);
for (int i=0;i<100;i++) {
QString qi=QString::number(i);
m_tableModel->setHeaderData(i,Qt::Vertical, qi);
}
for (int i=0;i<PcbController->getWaitingList().length();i++) {
QString name=PcbController->getWaitingList().at(i).getPcbName();
int Time=PcbController->getWaitingList().at(i).getPcbTime();
int pri=PcbController->getWaitingList().at(i).getPriority();
//setItem函数的第一个参数表示行号,第二个表示列号,第三个为要显示的数据
m_tableModel->setItem(row,lie,new QStandardItem(name));
lie++;
m_tableModel->setItem(row,lie,new QStandardItem(QString::number(Time)));
lie++;
m_tableModel->setItem(row,lie,new QStandardItem(QString::number(pri)));
row++;
lie=0;
}
// QVector<PCB>::iterator iter;
// //油饼?有时候可以有时候不行,煞笔
// for (iter=PcbController->getWaitingList().begin();iter!=PcbController->getWaitingList().end();iter++){
// QString n=PcbController->getWaitingList().begin()->getPcbName();
// qDebug()<<n;
// QString name=iter->getPcbName();
// qDebug()<<name;
// int Time=iter->getPcbTime();
// int pri=iter->getPriority();
// //setItem函数的第一个参数表示行号,第二个表示列号,第三个为要显示的数据
// m_tableModel->setItem(row,lie,new QStandardItem(name));
// lie++;
// m_tableModel->setItem(row,lie,new QStandardItem(QString::number(Time)));
// lie++;
// m_tableModel->setItem(row,lie,new QStandardItem(QString::number(pri)));
// row++;
// lie=0;
// }
qDebug()<<"调用reWaiting第二次";
}
void MainWindow::showTableViewHead()
{
reWaiting();//waiting
showTerminate();//terminate
showHanging();//hanging
}
void MainWindow::createAllConnect()
{
connect(addnewprocessdialog->getUi()->SurepushButton,SIGNAL(clicked()),this,SLOT(reWaiting()));
}
void MainWindow::setFirstButton()
{
QFont font;
//设置文字字体
font.setFamily("华文行楷");
//设置文字大小为50像素
font.setPixelSize(15);
FirstButton.setParent(this);
FirstButton.setGeometry(20,650,489,28);
FirstButton.setText(tr(" P1 6 4 "));
FirstButton.setFont(font);
FirstButton.setVisible(false);
ui->pushButton_4->setCheckable(true);
ui->pushButton_3->setCheckable(true);
ui->pushButton_2->setCheckable(true);
ui->pushButton->setCheckable(true);
FirstButton.setCheckable(true);
ui->pushButton_4->setDefault(false);
ui->pushButton_3->setDefault(false);
ui->pushButton_2->setDefault(false);
ui->pushButton->setDefault(false);
FirstButton.setDefault(false);
}
void MainWindow::showReadyList()
{
//谁有内容谁显示
ui->pushButton->setText(tr(" 空 空 空 "));
ui->pushButton_2->setText(tr(" 空 空 空 "));
ui->pushButton_3->setText(tr(" 空 空 空 "));
ui->pushButton_4->setText(tr(" 空 空 空 "));
int len=PcbController->getReadyList().length();
if (len==0){
return;
}
QString name=PcbController->getReadyList()[0].getPcbName();
QString time=QString::number(PcbController->getReadyList()[0].getPcbTime());
QString pri=QString::number(PcbController->getReadyList()[0].getPriority());
qDebug()<<name+" "+time+" "+pri;
ui->pushButton->setText(name+" "+time+" "+pri);
ui->pushButton->setVisible(true);
if (--len==0) return;
qDebug()<<"已添加到pushButton";
name=PcbController->getReadyList()[1].getPcbName();
time=QString::number(PcbController->getReadyList()[1].getPcbTime());
pri=QString::number(PcbController->getReadyList()[1].getPriority());
qDebug()<<name+" "+time+" "+pri;
ui->pushButton_2->setText(name+" "+time+" "+pri);
ui->pushButton_2->setVisible(true);
if (--len==0) return;
qDebug()<<"已添加到pushButton2";
name=PcbController->getReadyList()[2].getPcbName();
time=QString::number(PcbController->getReadyList()[2].getPcbTime());
pri=QString::number(PcbController->getReadyList()[2].getPriority());
qDebug()<<name+" "+time+" "+pri;
ui->pushButton_3->setText(name+" "+time+" "+pri);
ui->pushButton_3->setVisible(true);
if (--len==0) return;
qDebug()<<"已添加到pushButton3";
name=PcbController->getReadyList()[3].getPcbName();
time=QString::number(PcbController->getReadyList()[3].getPcbTime());
pri=QString::number(PcbController->getReadyList()[3].getPriority());
qDebug()<<name+" "+time+" "+pri;
ui->pushButton_4->setText(name+" "+time+" "+pri);
ui->pushButton_4->setVisible(true);
if (--len==0) return;
qDebug()<<"已添加到pushButton4";
qDebug()<<"readyList已显示";
}
void MainWindow::showTerminate()
{
//此函数的作用是显示Terminate表格中的内容
/*初始化Terminate队列*/
int row=0;//记录行数
int lie=0;//记录列数
t_tableModel->clear();//非常非常非常重要!!!!
t_tableModel->setHorizontalHeaderItem(0, new QStandardItem("进程名"));
t_tableModel->setHorizontalHeaderItem(1, new QStandardItem("运行时间"));
t_tableModel->setHorizontalHeaderItem(2, new QStandardItem("优先权"));
//setColumnWidth设置每一列的宽度
this->ui->terminate_tableView->setColumnWidth(0, 140); //设置列的宽度
this->ui->terminate_tableView->setColumnWidth(1, 140);
this->ui->terminate_tableView->setColumnWidth(2, 140);
/*设置行字段名*/
t_tableModel->setRowCount(100);
for (int i=0;i<100;i++) {
QString qi=QString::number(i);
t_tableModel->setHeaderData(i,Qt::Vertical, qi);
}
for (int i=0;i<PcbController->getTerminateList().length();i++) {
QString name=PcbController->getTerminateList().at(i).getPcbName();
int Time=PcbController->getTerminateList().at(i).getPcbTime();
int pri=PcbController->getTerminateList().at(i).getPriority();
//setItem函数的第一个参数表示行号,第二个表示列号,第三个为要显示的数据
t_tableModel->setItem(row,lie,new QStandardItem(name));
lie++;
t_tableModel->setItem(row,lie,new QStandardItem(QString::number(Time)));
lie++;
t_tableModel->setItem(row,lie,new QStandardItem(QString::number(pri)));
row++;
lie=0;
}
}
void MainWindow::showHanging()
{
//此函数的作用是显示Terminate表格中的内容
/*初始化Terminate队列*/
int row=0;//记录行数
int lie=0;//记录列数
h_tableModel->clear();//非常非常非常重要!!!!
h_tableModel->setHorizontalHeaderItem(0, new QStandardItem("进程名"));
h_tableModel->setHorizontalHeaderItem(1, new QStandardItem("运行时间"));
h_tableModel->setHorizontalHeaderItem(2, new QStandardItem("优先权"));
//setColumnWidth设置每一列的宽度
this->ui->hanging_tableView->setColumnWidth(0, 140); //设置列的宽度
this->ui->hanging_tableView->setColumnWidth(1, 140);
this->ui->hanging_tableView->setColumnWidth(2, 140);
/*设置行字段名*/
h_tableModel->setRowCount(100);
for (int i=0;i<100;i++) {
QString qi=QString::number(i);
h_tableModel->setHeaderData(i,Qt::Vertical, qi);
}
for (int i=0;i<PcbController->getHangingList().length();i++) {
QString name=PcbController->getHangingList().at(i).getPcbName();
int Time=PcbController->getHangingList().at(i).getPcbTime();
int pri=PcbController->getHangingList().at(i).getPriority();
//setItem函数的第一个参数表示行号,第二个表示列号,第三个为要显示的数据
h_tableModel->setItem(row,lie,new QStandardItem(name));
lie++;
h_tableModel->setItem(row,lie,new QStandardItem(QString::number(Time)));
lie++;
h_tableModel->setItem(row,lie,new QStandardItem(QString::number(pri)));
row++;
lie=0;
}
}
void MainWindow::GoToRunning()
{
if (PcbController->getRunningList().length()==0){
FirstButton.setVisible(false);
return;
}
FirstButton.setGeometry(20,650,489,28);
FirstButton.setVisible(true);
QString name=PcbController->getRunningList()[0].getPcbName();
QString time=QString::number(PcbController->getRunningList()[0].getPcbTime());
QString pri=QString::number(PcbController->getRunningList()[0].getPriority());
FirstButton.setText(name+" "+time+" "+pri);
m_animation->setPropertyName("geometry"); //指定动画属性名
m_animation->setDuration(1000);
m_animation->setStartValue(QRect(20,650,489,28));
m_animation->setEndValue(QRect(790,745,489,28));
m_animation->start();
}
void MainWindow::on_AddProcess_pushButton_clicked()
{
addnewprocessdialog->show();
}
void MainWindow::on_clearWaiting_pushButton_clicked()
{
int cnt=0;
QVector<PCB> w1=PcbController->getWaitingList();
for (int i=0;i<w1.length();i++) {
QString name=w1.at(i).getPcbName();
PcbController->deleteWaiting(name);
cnt++;
}
reWaiting();//重新显示Waiting队列
}
void MainWindow::on_pushButton_4_clicked(bool checked)
{
if(checked == true)
{
qDebug()<<"111";//选中
ui->pushButton_4->setDefault(false);
}
else
{
qDebug()<<"222";//取消选中
ui->pushButton_4->setDefault(true);
}
}
void MainWindow::on_pushButton_3_clicked(bool checked)
{
if(checked == true)
{
qDebug()<<"111";//选中
ui->pushButton_3->setDefault(false);
}
else
{
qDebug()<<"222";//取消选中
ui->pushButton_3->setDefault(true);
}
}
void MainWindow::on_pushButton_2_clicked(bool checked)
{
if(checked == true)
{
qDebug()<<"111";//选中
ui->pushButton_2->setDefault(false);
}
else
{
qDebug()<<"222";//取消选中
ui->pushButton_2->setDefault(true);
}
}
void MainWindow::on_pushButton_clicked(bool checked)
{
if(checked == true)
{
qDebug()<<"111";//选中
ui->pushButton->setDefault(false);
}
else
{
qDebug()<<"222";//取消选中
ui->pushButton->setDefault(true);
}
}
void MainWindow::on_Start_pushButton_clicked()
{
if (isCanStart){
if (QString::compare(ui->comboBox_2->currentText(),"自动运行")==0){
tim->start(1000);
Auto=true;
}else{
tim->stop();
Auto=false;
}
if (QString::compare(ui->comboBox->currentText(),"优先级调度")==0){
PriIsChange=true;
if (PcbController->getWaitingList().length()<4){
//Waiting长度小于4,则调用waiting长度的PCB
PcbController->transferWaitingToReady(PcbController->getWaitingList().length());
}else{
PcbController->transferWaitingToReady(4);//转运四个waitingPcb
}
PcbController->SortReadyList();//排序readyList
reWaiting();
showReadyList();
PcbController->ReadyChangeToRunning();
if (PcbController->getWaitingList().length()>0){
PcbController->transferWaitingToReady(1);//来一个
PcbController->SortReadyList();//排序readyList
reWaiting();//Waiting重新加载
showReadyList();//Ready重新显示
}
if (!(PcbController->ReadyChangeToRunning())){
//发生抢占
qDebug()<<"发生抢占";
//FirstButton.setVisible(false);
showReadyList();
GoToRunning();
}else{
showReadyList();
GoToRunning();
}
isCanStart=false;
}else{
//时间片轮转,不需要排序了
//先waiting到ready
TimerIsChange=true;
if (PcbController->getWaitingList().length()<4){
//Waiting长度小于4,则调用waiting长度的PCB
PcbController->transferWaitingToReady(PcbController->getWaitingList().length());
}else{
PcbController->transferWaitingToReady(4);//转运四个waitingPcb
}
reWaiting();
showReadyList();
PcbController->ReadyChangeToRunningTimer();
if (PcbController->getWaitingList().length()>0){
PcbController->transferWaitingToReady(1);//来一个
reWaiting();//Waiting重新加载
showReadyList();//Ready重新显示
}
if (!(PcbController->ReadyChangeToRunningTimer())){
//发生抢占
qDebug()<<"发生时间片抢占";
//FirstButton.setVisible(false);
showReadyList();
GoToRunning();
}else{
showReadyList();
GoToRunning();
}
isCanStart=false;
}
}else{
QMessageBox box;
box.setWindowTitle(tr("已经开始,请勿重复点击"));
box.setIcon(QMessageBox::Warning);
box.setText(tr("请点击下一步或者重新开始"));
box.addButton(tr("确定"),QMessageBox::AcceptRole);
if(box.exec()==QMessageBox::Accepted)
{
box.close();
}
}
}
void MainWindow::on_Next_pushButton_clicked()
{
if (isCanStart){
//还没开始
QMessageBox::warning(this,tr("未开始"),"请先点击开始运行");
return;
}
ui->label_5->setText("");
if (QString::compare(ui->comboBox->currentText(),"优先级调度")==0){
if (TimerIsChange){
//说明刚刚用的是时间片调度算法
QMessageBox::information(this,tr("更改算法"),"已更改为优先级调度算法");
TimerIsChange=false;
PriIsChange=true;
}
bool f=PcbController->aging();
if (!(f)&&PcbController->getRunningList().length()!=0){
//要去终止了
QString name=PcbController->getRunningList()[0].getPcbName();
QString time=QString::number(PcbController->getRunningList()[0].getPcbTime());
QString pri=QString::number(PcbController->getRunningList()[0].getPriority());
FirstButton.setText(name+" "+time+" "+pri);
PcbController->RunningToTerminate();
showTerminate();
PcbController->ReadyChangeToRunning();//running从0到1
//ui->pushButton->setVisible(false);
if (PcbController->getWaitingList().length()>0){
PcbController->transferWaitingToReady(1);//来一个
PcbController->SortReadyList();//排序readyList
reWaiting();//Waiting重新加载
//ui->pushButton->setVisible(true);
showReadyList();//Ready重新显示
GoToRunning();
}else{
showReadyList();//Ready重新显示
GoToRunning();
}
if (PcbController->getReadyList().length()==0){
return;
}
if (!(PcbController->ReadyChangeToRunning())){
//发生抢占
qDebug()<<"发生抢占";
//FirstButton.setVisible(false);
ui->label_5->setText("发生抢占!");
showReadyList();
GoToRunning();
}
}else if(!(f)&&PcbController->getRunningList().length()==0){
if (PcbController->getWaitingList().length()>0){
if (PcbController->getWaitingList().length()<4){
//Waiting长度小于4,则调用waiting长度的PCB
PcbController->transferWaitingToReady(PcbController->getWaitingList().length());
}else{
PcbController->transferWaitingToReady(4);//转运四个waitingPcb
}
PcbController->SortReadyList();//排序readyList
reWaiting();
showReadyList();
PcbController->ReadyChangeToRunning();
if (PcbController->getWaitingList().length()>0){
PcbController->transferWaitingToReady(1);//来一个
PcbController->SortReadyList();//排序readyList
reWaiting();//Waiting重新加载
showReadyList();//Ready重新显示
}
if (!(PcbController->ReadyChangeToRunning())){
//发生抢占
qDebug()<<"发生抢占";
//FirstButton.setVisible(false);
ui->label_5->setText("发生抢占!");
showReadyList();
GoToRunning();
}else{
showReadyList();
GoToRunning();
}
}else{
if (!Auto){
QMessageBox box;
box.setWindowTitle(tr("Running无内容"));
box.setIcon(QMessageBox::Warning);
box.setText(tr("已无进程可以调度,请重新添加进程"));
box.addButton(tr("确定"),QMessageBox::AcceptRole);
if(box.exec()==QMessageBox::Accepted)
{
box.close();
}
}
}
}else{
//正常情况
QString name=PcbController->getRunningList()[0].getPcbName();
QString time=QString::number(PcbController->getRunningList()[0].getPcbTime());
QString pri=QString::number(PcbController->getRunningList()[0].getPriority());
FirstButton.setText(name+" "+time+" "+pri);
if (PcbController->getReadyList().length()==0){
return;
}
if (!(PcbController->ReadyChangeToRunning())){
//发生抢占
//条件自带排序
qDebug()<<"发生抢占";
ui->label_5->setText("发生抢占!");
showReadyList();
GoToRunning();
}
}
}else{
//时间片调度算法
if (PriIsChange){
//说明刚刚用的是时间片调度算法
QMessageBox::information(this,tr("更改算法"),"已更改为时间片轮转调度算法");
TimerIsChange=true;
PriIsChange=false;
}
bool f=PcbController->agingTimer();
if (!(f)&&PcbController->getRunningList().length()!=0){
//要去终止了
QString name=PcbController->getRunningList()[0].getPcbName();
QString time=QString::number(PcbController->getRunningList()[0].getPcbTime());
QString pri=QString::number(PcbController->getRunningList()[0].getPriority());
FirstButton.setText(name+" "+time+" "+pri);
PcbController->RunningToTerminate();
showTerminate();
PcbController->ReadyChangeToRunningTimer();//running从0到1
//ui->pushButton->setVisible(false);
if (PcbController->getWaitingList().length()>0){
PcbController->transferWaitingToReady(1);//来一个
reWaiting();//Waiting重新加载
showReadyList();//Ready重新显示
GoToRunning();
}else{
showReadyList();//Ready重新显示
GoToRunning();
}
if (PcbController->getReadyList().length()==0){
return;
}
if (!(PcbController->ReadyChangeToRunningTimer())){
//发生抢占
qDebug()<<"发生抢占";
ui->label_5->setText("发生抢占!");
showReadyList();
GoToRunning();
}
}else if(!(f)&&PcbController->getRunningList().length()==0){
if (PcbController->getWaitingList().length()>0){
if (PcbController->getWaitingList().length()<4){
//Waiting长度小于4,则调用waiting长度的PCB
PcbController->transferWaitingToReady(PcbController->getWaitingList().length());
}else{
PcbController->transferWaitingToReady(4);//转运四个waitingPcb
}
reWaiting();
showReadyList();
PcbController->ReadyChangeToRunningTimer();
if (PcbController->getWaitingList().length()>0){
PcbController->transferWaitingToReady(1);//来一个
reWaiting();//Waiting重新加载
showReadyList();//Ready重新显示
}
if (!(PcbController->ReadyChangeToRunningTimer())){
//发生抢占
qDebug()<<"发生抢占";
ui->label_5->setText("发生抢占!");
showReadyList();
GoToRunning();
}else{
showReadyList();
GoToRunning();
}
}else{
if (!Auto){
QMessageBox box;
box.setWindowTitle(tr("Running无内容"));
box.setIcon(QMessageBox::Warning);
box.setText(tr("已无进程可以调度,请重新添加进程"));
box.addButton(tr("确定"),QMessageBox::AcceptRole);
if(box.exec()==QMessageBox::Accepted)
{
box.close();
}
}
}
}else{
//正常情况
QString name=PcbController->getRunningList()[0].getPcbName();
QString time=QString::number(PcbController->getRunningList()[0].getPcbTime());
QString pri=QString::number(PcbController->getRunningList()[0].getPriority());
FirstButton.setText(name+" "+time+" "+pri);
if (PcbController->getReadyList().length()==0){
return;
}
if (!(PcbController->ReadyChangeToRunningTimer())){
//发生抢占
qDebug()<<"发生抢占";
ui->label_5->setText("发生抢占!");
showReadyList();
GoToRunning();
}
}
}
}
void MainWindow::on_hanging_pushButton_clicked()
{
if (ui->radioButton->isChecked()){
//被选中
qDebug()<<"按钮一被选中";
//首先ready的进hanging(这个在controller里面实现)
if(!(PcbController->ReadyToHanging(0))){
QMessageBox box;
box.setWindowTitle(tr("选中的进程不存在"));
box.setIcon(QMessageBox::Warning);
box.setText(tr("选中的进程为空,请重新选择或向就绪队列添加进程"));
box.addButton(tr("确定"),QMessageBox::AcceptRole);
if(box.exec()==QMessageBox::Accepted)
{
box.close();
}
return;
}
showHanging();
//waiting会补充到ready,补充一个
if (PcbController->getWaitingList().length()>0){
PcbController->transferWaitingToReady(1);
}
reWaiting();
PcbController->SortReadyList();
showReadyList();
if (!(PcbController->ReadyChangeToRunning())){
//发生抢占
qDebug()<<"发生抢占";
//FirstButton.setVisible(false);
showReadyList();
GoToRunning();
}
}else if (ui->radioButton_2->isChecked()){
//被选中
qDebug()<<"按钮二被选中";
//首先ready的进hanging(这个在controller里面实现)
if(!(PcbController->ReadyToHanging(1))){
QMessageBox box;
box.setWindowTitle(tr("选中的进程不存在"));
box.setIcon(QMessageBox::Warning);
box.setText(tr("选中的进程为空,请重新选择或向就绪队列添加进程"));
box.addButton(tr("确定"),QMessageBox::AcceptRole);
if(box.exec()==QMessageBox::Accepted)
{
box.close();
}
return;
}
showHanging();
//waiting会补充到ready,补充一个
if (PcbController->getWaitingList().length()>0){
PcbController->transferWaitingToReady(1);
}
reWaiting();
PcbController->SortReadyList();
showReadyList();
if (!(PcbController->ReadyChangeToRunning())){
//发生抢占
qDebug()<<"发生抢占";
//FirstButton.setVisible(false);
showReadyList();
GoToRunning();
}
}else if (ui->radioButton_3->isChecked()){
//被选中
qDebug()<<"按钮三被选中";
//首先ready的进hanging(这个在controller里面实现)
if(!(PcbController->ReadyToHanging(2))){
QMessageBox box;
box.setWindowTitle(tr("选中的进程不存在"));
box.setIcon(QMessageBox::Warning);
box.setText(tr("选中的进程为空,请重新选择或向就绪队列添加进程"));
box.addButton(tr("确定"),QMessageBox::AcceptRole);
if(box.exec()==QMessageBox::Accepted)
{
box.close();
}
return;
}
showHanging();
//waiting会补充到ready,补充一个
if (PcbController->getWaitingList().length()>0){
PcbController->transferWaitingToReady(1);
}
reWaiting();
PcbController->SortReadyList();
showReadyList();
if (!(PcbController->ReadyChangeToRunning())){
//发生抢占
qDebug()<<"发生抢占";
//FirstButton.setVisible(false);
showReadyList();
GoToRunning();
}
}else if (ui->radioButton_4->isChecked()){
//被选中
qDebug()<<"按钮四被选中";
//首先ready的进hanging(这个在controller里面实现)
if(!(PcbController->ReadyToHanging(3))){
QMessageBox box;
box.setWindowTitle(tr("选中的进程不存在"));
box.setIcon(QMessageBox::Warning);
box.setText(tr("选中的进程为空,请重新选择或向就绪队列添加进程"));
box.addButton(tr("确定"),QMessageBox::AcceptRole);
if(box.exec()==QMessageBox::Accepted)
{
box.close();
}
return;
}
showHanging();
//waiting会补充到ready,补充一个
if (PcbController->getWaitingList().length()>0){
PcbController->transferWaitingToReady(1);
}
reWaiting();
PcbController->SortReadyList();
showReadyList();
if (!(PcbController->ReadyChangeToRunning())){
//发生抢占
qDebug()<<"发生抢占";
//FirstButton.setVisible(false);
showReadyList();
GoToRunning();
}
}
}
void MainWindow::on_relieveHanging_pushButton_clicked()
{
if (!(PcbController->HangingToWaiting(cell))){
//没找到
QMessageBox box;
box.setWindowTitle(tr("没有找到进程"));
box.setIcon(QMessageBox::Warning);
box.setText(tr("请选择进程的名字"));
box.addButton(tr("确定"),QMessageBox::AcceptRole);
if(box.exec()==QMessageBox::Accepted)
{
box.close();
}
}else{
//找到,则重新显示
reWaiting();
showHanging();
}
}
void MainWindow::on_hanging_tableView_clicked(const QModelIndex &index)
{
cell = index.data().toString();
}
void MainWindow::on_restart_pushButton_clicked()
{
//点击重新开始会停止
TimerIsChange=false;
PriIsChange=false;
tim->stop();
Auto=false;
isCanStart=true;
//全部清空
PcbController->reStart();
//重新显示waiting队列
reWaiting();
//重新显示ready队列
ui->pushButton->setText(tr(" 空 空 空 "));
ui->pushButton_2->setText(tr(" 空 空 空 "));
ui->pushButton_3->setText(tr(" 空 空 空 "));
ui->pushButton_4->setText(tr(" 空 空 空 "));
FirstButton.setGeometry(20,650,489,28);
FirstButton.setVisible(false);
//重新显示terminate队列
showTerminate();
showHanging();
}
void MainWindow::on_pushButton_5_clicked()
{
tim->stop();
Auto=false;
QMessageBox::information(this,tr("暂停成功"),"已暂停自动运行");
}
void MainWindow::on_pushButton_6_clicked()
{
if (!(QString::compare(ui->comboBox_2->currentText(),"自动运行")==0)){
//如果现在是自动运行并且不能再开始(说明已经开始了)
QMessageBox box;
box.setWindowTitle(tr("不可以继续"));
box.setIcon(QMessageBox::Warning);
box.setText(tr("请选择自动运行模式"));
box.addButton(tr("确定"),QMessageBox::AcceptRole);
if(box.exec()==QMessageBox::Accepted)
{
box.close();
}
return;
}
if (isCanStart){
//能再开始(说明没开始了)
QMessageBox box;
box.setWindowTitle(tr("不可以继续"));
box.setIcon(QMessageBox::Warning);
box.setText(tr("请先开始运行"));
box.addButton(tr("确定"),QMessageBox::AcceptRole);
if(box.exec()==QMessageBox::Accepted)
{
box.close();
}
return;
}
tim->start(1000);
Auto=true;
QMessageBox::information(this,tr("继续成功"),"已继续自动运行");
}
界面展示:
六、实验结论
通过Qt实现了处理机调度算法的图形化显示,可以直观地看出处理调度算法的整个工作流程。因此通过本次实验可以发现,动态优先级优点是使相应的优先级调度算法比较灵活、科学,可防止有些进程一直得不到调度,也可防止有些进程长期垄断处理机。动态优先级缺点是需要花费相当多的执行程序时间,因而花费的系统开销比较大。并且会出现饥饿的问题,解决方式是老化。
七、实验小结
通过本次实验,不仅深刻地熟悉了处理机调度算法的流程和原理,并且进一步掌握了用Qt进行图形化界面展示的学习方法。在设计程序架构,调试代码时,编程能力有了更大的提高。
MVC的架构设计可以更有效的分离前端和后端,前端只负责显示界面,而后端的队列之间的转换,排序等等工作都可以交给Controller来实现。
本次实验卡我最长时间的是关于动画的实现,一开始我打算用一个Q Timer来实现动画效果,即设定一个槽函数,用来改变按钮的坐标,再链接Q Timer和此函数,实现每隔一段时间调用此函数,实现按钮的连续移动。但是Q Timer调用动画总会出现时间上的不合逻辑,比如我先使用的start(),但是按钮的移动却在其他代码运行之后才开始移动。后来改用了Q property Animation 类实现了动画效果。
本次实验出现的一些小bug都比较成功的解决了,得益于我对于debug使用的熟练,并且对一些调试方法颇有心得,通过这个小项目的学习,可以更熟练的掌握这些能力,编程的思路也更加清晰。
(本实验代码开源在 处理机调度实验代码 上)