提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 前言
- 一、时间片转轮算法是什么?
- 二、代码实现
- 1.总体设计思路
- (1)ui界面
- (2)MyThread类的构造
- (3)CPU类的构造
- (4)Widget类的构造
- 2.代码实现
- (1)代码结构
- (2)MyThread类
- (3)CPU类
- (4)Widget类
- 3.运行效果
- 总结
前言
本文介绍qt实现时间片转轮算法
一、时间片转轮算法是什么?
cpu执行进程时,可以给每一个进程一个时间片,时间片完马上就去执行下一个进程,并把当前进程放到执行队列的最后。
不过需要注意的是,时间片的长度不能给的太长,也不能给的太短。太长的话,就相当于先来先服务算法啦,,太短的话,频繁地切换进程,会增加不必要的开销.
二、代码实现
1.总体设计思路
(1)ui界面
如上显示,一个 开始 按钮用来启动动画过程,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)代码结构
(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界面移动对应的进程图片
其余几个进程也类似
(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处理过程中的进程移动
(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.运行效果
总结
以上就是今天要讲的内容,本文简单地介绍了时间片算法的实现