QWaitConditon应用

背景:在编写多线程的时候,有的线程需要一直的执行下去,永不停止,但是有的线程是需要它能够在我们的控制下自由地的开始和暂停。那么常用的方法就是让线程等待一个标志,标志为假就睡眠,当标志为真就唤醒。Qt提供了类似的机制,那就是QWaitConditon类。

一、QWaitConditon简介

线程如何睡眠?

调用QWaitCondition的wait函数将使得调用它的线程进入睡眠状态

线程如何醒来?

在另外的线程中调用QWaitConditon的wakeOne或者wakeAll方法将唤醒等待它的线程

二、代码示例

线程类

//workthread.h
#include <QThread>
class WorkThread : public QThread
{
    Q_OBJECT
public:
    explicit WorkThread(QObject *parent = 0);
protected:
    void run();
private:
    int i;
};
//workthread.cpp
#include "WorkThread.h"
#include <qwaitcondition>
#include <qmutex>
#include <qtdebug>
QWaitCondition pressed;
QMutex mutex;
bool bStart;

WorkThread::WorkThread(QObject *parent) : QThread(parent)
{
    i=0;
    bStart=true;
}

void WorkThread::run()
{
    while(1)
    {
      if(bStart==false)                             //当bStart变量为假的时候才让线程睡眠
      {
        mutex.lock();
        pressed.wait(&mutex);                       //线程等待press.wakeOne或者press.wakeAll而睡眠
        mutex.unlock();
      }
     sleep(1);                                      //控制qDebug打印频率
     qDebug()<<"work thread is running:"<<i++<<'\n';//线程的主体,在Qt的调试区打印出来,代表线程的进行
    }
}

界面类

//dialog.h
#include <QDialog>

namespace Ui {
class Dialog;
}

class Dialog : public QDialog
{
    Q_OBJECT
    
public:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();
    
private slots:
    void on_pushButton_clicked();

private:
    Ui::Dialog *ui;

};
//dialog.cpp
#include "dialog.h"
#include "ui_dialog.h"
#include 
#include 

extern bool bStart;
extern QWaitCondition pressed;
extern QMutex mutex;

Dialog::Dialog(QWidget *parent) :QDialog(parent),ui(new Ui::Dialog)
{
    ui->setupUi(this);
}

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

void Dialog::on_pushButton_clicked()
{
    if(bStart==false)                           //点击按钮前开始状态为假
    {
        bStart=true;                            //点击按钮后开始状态为真
        ui->pushButton->setText(tr("暂停线程"));//按钮的文字显示"暂停线程"
        pressed.wakeAll();                      //唤醒因pressed.wait而睡眠的线程
    }
    else                                        //点击按钮前开始状态为真
    {
        bStart=false;                           //点击按钮后开始状态为假
        ui->pushButton->setText(tr("开始线程"));//按钮的文字显示为"开始线程"
    }
}

主函数

#include "dialog.h"
#include <QApplication>
#include <QTextCodec>
#include <WorkThread.h>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QTextCodec::setCodecForTr(QTextCodec::codecForName("utf-8"));

    WorkThread work;
    work.start();

    Dialog w;
    w.show();
    
    return a.exec();
}
界面UI

                           

效果:

开始运行的时候按钮显示暂停线程,这时候可以看见Qt调用窗口有打印信息出现,说明线程在不停的运行

点击按钮,文字显示为开始线程,现在打印信息也没有了,说明线程没有运行了

再次点击按钮,文字再次显示为暂停线程,这个时候打印信息又开始显示了,并且接着上面的数字

存在问题:

当bStart为假的时候,线程并不是立即休眠,而是要等到线程的程序执行到判断bStart的时候才会睡眠,所以有一定的延时



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值