背景:在编写多线程的时候,有的线程需要一直的执行下去,永不停止,但是有的线程是需要它能够在我们的控制下自由地的开始和暂停。那么常用的方法就是让线程等待一个标志,标志为假就睡眠,当标志为真就唤醒。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();
- }
效果:
开始运行的时候按钮显示暂停线程,这时候可以看见Qt调用窗口有打印信息出现,说明线程在不停的运行
点击按钮,文字显示为开始线程,现在打印信息也没有了,说明线程没有运行了
再次点击按钮,文字再次显示为暂停线程,这个时候打印信息又开始显示了,并且接着上面的数字
存在问题:
当bStart为假的时候,线程并不是立即休眠,而是要等到线程的程序执行到判断bStart的时候才会睡眠,所以有一定的延时