背景:在编写多线程的时候,有的线程需要一直的执行下去,永不停止,但是有的线程是需要它能够在我们的控制下自由地的开始和暂停。那么常用的方法就是让线程等待一个标志,标志为假就睡眠,当标志为真就唤醒。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的时候才会睡眠,所以有一定的延时