QThread中的非阻塞式延迟函数验证

非阻塞延迟函数

问题来源

在工作中,使用开源的Openpilot编写的机器人配置工具,调用海康SDK来控制相机变焦调焦时,调焦问题不大,但是在变倍数时,焦距值跟着变化,以前这个缺陷没有处理,我在处理过程中,调试时发现是相机硬件需要时间去刷新这个值,但是从SDK去读取也是非阻塞的,也就是说,这个值在变化中也可读出来。因此,考虑到加入阻塞延时操作,但是今天被同事提醒,在UI线程中不能加入延时。折腾一下午,试了试非阻塞函数,觉得可行性很高,记录于此。
声明: 全部分代码来源于网络
详情可见 :Qt修炼手册11_多线程编程和QThread类

demo

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 
#include 
#include 
#include 
#include 

namespace Ui {
class MainWindow;
}
class MyThread : public QThread
{
    Q_OBJECT
public:
    MyThread(int num);
private:
    bool threadStop;
    int number;
    QMutex mutex;
public:
    void stop();
protected:
    void run();
};

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    MyThread *thread1;
    MyThread *thread2;
    void NonBlockingMsSleep(int ms);
signals:
    void mySignal();

private slots:
    void btn_start();
    void btn_stop();
    void btn_isRunning();
    void btn_isFinished();

    void on_pushButton_clicked();

private:

    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
#include
#include "myobject.h"
MyThread::MyThread(int num)
{}

void MyThread::stop()
{
    threadStop = true;
    qDebug("[%d] Thread stop", number);
}

void MyThread::run()
{
    threadStop = false;
    int i = 0;

    while(!threadStop)
    {
        mutex.lock();
        qDebug("[%d] MyThread %d", number, i);
        i++;
        msleep(50);
        mutex.unlock();
    }
}

///////////////////////////////////////////////////////
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    thread1 = new MyThread(1);
    thread2 = new MyThread(2);

    QPushButton *btn_start = new QPushButton("START", this);
    btn_start->setGeometry(10, 10, 80, 40);
    QPushButton *btn_stop = new QPushButton("STOP", this);
    btn_stop->setGeometry(100, 10, 80, 40);
    QPushButton *btn_isRunning = new QPushButton("IsRunning", this);
    btn_isRunning->setGeometry(200, 10, 100, 40);
    QPushButton *btn_isFinished = new QPushButton("IsFinished", this);
    btn_isFinished->setGeometry(310, 10, 100, 40);

    connect(btn_start,      SIGNAL(clicked()), this, SLOT(btn_start()));
    connect(btn_stop,       SIGNAL(clicked()), this, SLOT(btn_stop()));
    connect(btn_isRunning,  SIGNAL(clicked()), this, SLOT(btn_isRunning()));
    connect(btn_isFinished, SIGNAL(clicked()), this, SLOT(btn_isFinished()));
}

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

void MainWindow::NonBlockingMsSleep(int ms)
{
    QTime dieTime = QTime::currentTime().addMSecs(ms);
    while( QTime::currentTime() < dieTime )
        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
}


void MainWindow::btn_start()
{
    thread1->start();
    thread2->start();
}

void MainWindow::btn_stop()
{
    thread1->stop();
    thread2->stop();
}

void MainWindow::btn_isRunning()
{
    if(thread1->isRunning())
        qDebug("[1] Thread is running");
    else
        qDebug("[1] Thread is not running");

    if(thread2->isRunning())
        qDebug("[2] Thread is running");
    else
        qDebug("[2] Thread is not running");
}

void MainWindow::btn_isFinished()
{
    if(thread1->isFinished())
        qDebug("[1] Thread Finish");
    else
        qDebug("[1] Thread not Finish");

    if(thread2->isFinished())
        qDebug("[2] Thread Finish");
    else
        qDebug("[2] Thread not Finish");
}



void MainWindow::on_pushButton_clicked()
{
    qDebug("NonBlockingMsSleep start");
    NonBlockingMsSleep(1000);
    qDebug("NonBlockingMsSleep end");

}

函数NonBlockingMsSleep即为非阻塞延时函数,我的理解就是,它的实现类似于使用单片机的定时器功能。

调试界面与验证结果

图中按下去的PushButton会发送clicked()信号,其槽函数on_pushButton_clicked()是用ui文件来绑定的,所以未在代码中体现,实际上
ui->setupUi(this);这句话执行后,就已经自动帮你connect了ui文件中编辑的信号与槽。
而qDebug信息则表明,延时不会阻塞其他线程。

你可能感兴趣的:(qt)