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