提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、时间片转轮算法是什么?
  • 二、代码实现
  • 1.总体设计思路
  • (1)ui界面
  • (2)MyThread类的构造
  • (3)CPU类的构造
  • (4)Widget类的构造
  • 2.代码实现
  • (1)代码结构
  • (2)MyThread类
  • (3)CPU类
  • (4)Widget类
  • 3.运行效果
  • 总结

前言

本文介绍qt实现时间片转轮算法

一、时间片转轮算法是什么?

cpu执行进程时,可以给每一个进程一个时间片,时间片完马上就去执行下一个进程,并把当前进程放到执行队列的最后。
不过需要注意的是,时间片的长度不能给的太长,也不能给的太短。太长的话,就相当于先来先服务算法啦,,太短的话,频繁地切换进程,会增加不必要的开销.

二、代码实现

1.总体设计思路

(1)ui界面

python 时间片轮转调度 时间片轮转调度程序_#include


如上显示,一个 开始 按钮用来启动动画过程,1234为四个Label标签,用来粘贴所得的图片并代表四个进程。最上面分为三个部分, 进程准备,CPU处理,处理完成。进程会依次经历进程准备,CPU处理,处理完成三个过程。

(2)MyThread类的构造

构造该类的目的,该类继承QThread,四个MyThread的对象对应ui界面有四个进程对象,在run()函数中发送信号,在主线程触发对应的槽函数并移动对应的图片。(该类起作用的主要时间为进程准备阶段)
为什么要在多线程中发信号:
因为这里的总体发信号操作是一个耗时操作,不能在主线程里面做。(做了就非常卡顿)
为什么不直接在多线程里操作ui界面:
qt的机制限制了ui只能在主线程里面操作否则卡顿,详细的信息就不展开讲啦。

(3)CPU类的构造

构造该类的目的,该类继承QThread,在CPU处理阶段,循环向主线程发送信号。主线程触发对应的槽函数,移动在CPU处理阶段的进程图片。

(4)Widget类的构造

数据成员:
MyThread的四个对象对应四个进程,CPU的一个对象。还要加一个队列,用来模拟CPU处理时,时间片算法的体现。

在该类的构造函数里面加入一若干connect函数,主要有四个MyThread的对象,与该类实现四个进程在进程准备过程中ui界面的移动的关联。然后就是CPU对象与 在 CPU处理过程中的ui界面的移动的关联,再然后就是若干初始化。

2.代码实现

(1)代码结构

python 时间片轮转调度 时间片轮转调度程序_qt_02

(2)MyThread类

mythread.h

#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QThread>
#include <QDebug>
#include <QObject>
#include "synchapi.h"
#include <QWidget>


class MyThread : public QThread
{
    Q_OBJECT
    bool isRun = 1;
public:
    bool flag=0;
    MyThread();
    void run();
    void changeIsRun();
//signals:
signals:
    void move();
};

#endif // MYTHREAD_H

mythread.cpp

#include "mythread.h"

MyThread::MyThread()
{

}

void MyThread::run()
{
    while(isRun){
        qDebug()<<"emit ....\n";
        msleep(50);
        emit move();
    }
}

void MyThread::changeIsRun()
{
    isRun = !isRun;
}

多的东西就不啰嗦啦。这里就介绍一下run函数里的move()信号代表什么意思

发射一次这个信号,就是会在ui界面移动对应的进程图片

python 时间片轮转调度 时间片轮转调度程序_#include_03


其余几个进程也类似

(3)CPU类

cpu.h

#ifndef CPU_H
#define CPU_H
#include <QThread>
#include <QDebug>
class CPU : public QThread
{
    Q_OBJECT
private:
    bool isRun=1;
public:
    void run();
    CPU();
signals:
    void wakeMoveInQue();
};

#endif // CPU_H

cpu.cpp

#include "cpu.h"

void CPU::run()
{
    while(isRun){
        msleep(50);
        emit wakeMoveInQue();
        qDebug()<<"cpu emit...";
    }
}

CPU::CPU()
{

}

同样的不啰嗦,run函数里面的wakeMoveInQue信号对应的是 在ui界面在 CPU处理过程中的进程移动

python 时间片轮转调度 时间片轮转调度程序_ui界面_04

(4)Widget类

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QPainter>
#include <QLabel>
#include <QKeyEvent>
#include <QDebug>
#include <QQueue>
#include "cpu.h"
#include "synchapi.h"
#include "mythread.h"
namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT
private:
//    QLabel* picLabel;
    MyThread th_red,th_yellow,th_blue,th_green;
    int flag[4]={0};
    QQueue<QLabel*> que;
    CPU cpu;
    bool isCPU=0;
public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();
    void paintEvent(QPaintEvent *);
    void init();
public slots:
    void moveRed();
    void moveYellow();
    void moveBlue();
    void moveGreen();
    void moveInQue();
signals:
    void wakeMoveSignal();
private slots:
    void on_pushButton_clicked();

private:
    Ui::Widget *ui;
};

#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <time.h>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    init();
    cpu.start();
    ui->label_hong->setFixedSize(50,50);
    ui->label_huang->setFixedSize(50,50);
    ui->label_lan->setFixedSize(50,50);
    ui->label_lv->setFixedSize(50,50);
    connect(&th_red,SIGNAL(move()),this,SLOT(moveRed()));
    connect(&th_yellow,SIGNAL(move()),this,SLOT(moveYellow()));
    connect(&th_blue,SIGNAL(move()),this,SLOT(moveBlue()));
    connect(&th_green,SIGNAL(move()),this,SLOT(moveGreen()));
    connect(&cpu,SIGNAL(wakeMoveInQue()),this,SLOT(moveInQue()));
}

Widget::~Widget()
{
    delete ui;
}

void Widget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QPixmap pix;
    pix.load(":/images/img/hongqiu.jpg");
    painter.drawPixmap(ui->label_hong->x(),ui->label_hong->y(),ui->label_hong->width(),ui->label_hong->height(),pix);
    pix.load(":/images/img/huangqiu.png");
    painter.drawPixmap(ui->label_huang->x(),ui->label_huang->y(),ui->label_huang->width(),ui->label_huang->height(),pix);
    pix.load(":/images/img/lanqiu.webp");
    painter.drawPixmap(ui->label_lan->x(),ui->label_lan->y(),ui->label_lan->width(),ui->label_lan->height(),pix);
    pix.load(":/images/img/lvqiu.jpg");
    painter.drawPixmap(ui->label_lv->x(),ui->label_lv->y(),ui->label_lv->width(),ui->label_lv->height(),pix);
}

void Widget::init()
{
    srand((int)time(0));
    int x;
    x=rand()%200;
    ui->label_hong->move(ui->label_hong->x()+x,ui->label_hong->y());
    x=rand()%200;
    ui->label_huang->move(ui->label_huang->x()+x,ui->label_huang->y());
    x=rand()%200;
    ui->label_lan->move(ui->label_lan->x()+x,ui->label_lan->y());
    x=rand()%200;
    ui->label_lv->move(ui->label_lv->x()+x,ui->label_lv->y());
}

void Widget::moveYellow()
{
    int x=0,y=0;
    qDebug()<<"接收到啦\n";
    x = ui->label_huang->x() + 5;
    if(x<400){
        ui->label_huang->move(x, ui->label_huang->y());
    }
    else{
        qDebug()<<"超啦超啦\n";
        if(th_yellow.flag==0)
            que.enqueue(ui->label_huang);
//        startCPU();
        th_yellow.flag=1;
        th_yellow.exit();
    }
}

void Widget::moveBlue()
{
    int x=0,y=0;
    qDebug()<<"接收到啦\n";
    x = ui->label_lan->x() + 5;
    if(x<400){
        ui->label_lan->move(x, ui->label_lan->y());
    }
    else{
        qDebug()<<"超啦超啦\n";
        if(th_blue.flag==0)
            que.enqueue(ui->label_lan);
        th_blue.flag=1;
        th_blue.exit();
    }
}

void Widget::moveGreen()
{
    int x=0,y=0;
    qDebug()<<"接收到啦\n";
    x = ui->label_lv->x() + 5;
    if(x<400){
        ui->label_lv->move(x, ui->label_lv->y());
    }
    else{
        qDebug()<<"超啦超啦\n";
        if(th_green.flag==0)
            que.enqueue(ui->label_lv);
        th_green.flag=1;
    }
}

void Widget::moveRed()
{
    int x=0,y=0;
    qDebug()<<"接收到啦\n";
    x = ui->label_hong->x() + 5;
    if(x<400){
        ui->label_hong->move(x, ui->label_hong->y());
    }
    else{
        qDebug()<<"超啦超啦\n";
        if(th_red.flag==0)
            que.enqueue(ui->label_hong);
        th_red.flag=1;
    }
}


void Widget::moveInQue()
{
    QLabel *label;
    qDebug()<<"moveInQue接收到啦.....\n"<<que.size();
    if(!que.empty()){
        label = que.head();
        que.dequeue();
        label->move(label->x()+5,label->y());
        if(label->x()<800){
            que.enqueue(label);
        }
    }
}

void Widget::on_pushButton_clicked()
{
    if(ui->pushButton->text()==tr("开始")){
        ui->pushButton->setText(tr("重置"));
        th_blue.start();
        th_green.start();
        th_yellow.start();
        th_red.start();
    }
    else{
        srand(int(time(0)));
        int x;
        x = rand()%200+100;
        ui->label_hong->move(x,ui->label_hong->y());
        x = rand()%200+100;
        ui->label_lv->move(x,ui->label_lv->y());
        x = rand()%200+100;
        ui->label_lan->move(x,ui->label_lan->y());
        x = rand()%200+100;
        ui->label_huang->move(x,ui->label_huang->y());
        th_blue.flag=0;
        th_green.flag=0;
        th_red.flag=0;
        th_yellow.flag=0;
        while(!que.empty()){
            que.dequeue();
        }
    }
}

还是一样,多的不啰嗦啦(前面设计思路里面讲的够详细啦)。这里对我而言比较新的知识点就是paintEvent函数,我是通过它在UI界面上将图片贴到Label上的

3.运行效果

python 时间片轮转调度 时间片轮转调度程序_python 时间片轮转调度_05

总结

以上就是今天要讲的内容,本文简单地介绍了时间片算法的实现