操作系统原理 实验一 《处理机调度 CPU Scheduling》

提示:实验源码见最下方


一、实验目的

多道系统中,当就绪进程数大于处理机数时,须按照某种策略决定哪些进程优先占用处理机。本实验模拟实现处理机调度,加深了解处理机调度的工作过程。

二、实验内容

    选择一个调度算法,实现处理机调度。

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设计细节分析:

  1. 在程序初始化的时候,会自动从数据库调用已存在的后备队列的PCB数据,并显示出来; 2.点击开始运行按钮,程序会根据选定的自动/手动模式和调度算法类型开始进行CPU调度; 3.点击开始运行按钮后,不可以再点击,否则程序会发出警告信息,但是可以进行下一步,重新开始等其他操作; 4.在点击重新开始按钮后,程序恢复到最初始状态,此时点击开始运行按钮可以重新开始新一轮的调度;
  1. 在程序开始运行后,点击下一步,将正在运行的进程老化,并且如果此时有抢占的话会发生抢占事件;
    6.自动模式下,将自动调用下一步无需手点;
    7.当没有进程可以调用时,点击下一步,则会跳出警告,如未出现警告,将自动模式暂停即可;

             8.算法切换可以在运行的过程中切换,此时会提示切换成功;

             9.自动手动可以实时切换。

             10.选择挂起队列中的进程的名字,点击解挂,即可解挂,解挂后的进程会被放到后备队列的头部;

             11.1.添加进程不可以与现存在的进程重名,否则会警告; 添加进程的时间必须是大于零的整数,否则会警告; 进程名和时间必须都填入,否则会警告;

3.详细设计

      只展示部分细节:

  1. .调用关系: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指针用来初始化调用数据库的内容。
  2. 后台队列之间的转移:

            例如:后备队列到就绪队列:

五、实验代码

  只展示部分实验代码:

#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使用的熟练,并且对一些调试方法颇有心得,通过这个小项目的学习,可以更熟练的掌握这些能力,编程的思路也更加清晰。

(本实验代码开源在 处理机调度实验代码 上)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值