描述可能比较麻烦,还是直接上代码吧!
main.cpp
#include <QApplication>
#include "mainpage.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainPage page;
page.show();
return a.exec();
}
mainpage.h
#ifndef MAINPAGE_H
#define MAINPAGE_H
#include <QWidget>
#include "thread1.h"
class MainPage : public QWidget
{
Q_OBJECT
public:
explicit MainPage(QWidget *parent = 0);
~MainPage();
thread1 *th1;
private slots:
void doClick();
};
#endif // MAINPAGE_H
thread1.h
#ifndef THREAD1_H
#define THREAD1_H
#include <QThread>
#include <QWaitCondition>
#include "thread2.h"
#include <QMutex>
class thread1 : public QThread
{
Q_OBJECT
public:
explicit thread1(QObject *parent = 0);
void run();
void wakeFunc();
private:
QWaitCondition cond;
QMutex mutex;
thread2 th2;
};
#endif // THREAD1_H
thread2.h
#ifndef THREAD2_H
#define THREAD2_H
#include <QThread>
class thread2 : public QThread
{
Q_OBJECT
public:
explicit thread2(QObject *parent = 0);
void run();
};
#endif // THREAD2_H
mainpage.cpp
#include "mainpage.h"
#include <QDebug>
#include <QPushButton>
MainPage::MainPage(QWidget *parent) :
QWidget(parent)
{
th1=new thread1;
this->resize(100, 40);
QPushButton *pb=new QPushButton("按钮", this);
pb->resize(50, 20);
pb->move(10, 10);
connect(pb, SIGNAL(clicked()), this, SLOT(doClick()));
}
MainPage::~MainPage()
{
}
void MainPage::doClick()
{
qDebug()<<"button clicked!";
th1->wakeFunc();
}
thread1.cpp
#include "thread1.h"
#include <QDebug>
thread1::thread1(QObject *parent) :
QThread(parent)
{
}
void thread1::wakeFunc()
{
if(!isRunning()){
start();
}else{
cond.wakeOne();
}
}
void thread1::run()
{
static int x=0;
qDebug()<<"进入thread1的run函数";
while(true){
qDebug()<<"-------> 1 <---------";
mutex.lock();
if(++x>3) th2.start();
qDebug() << "进入thread1的while循环,x值为"<<x;
cond.wait(&mutex); //当处于wait状态时mutex会被暂时释放,并阻塞在这个地方;当线程被cond.wakeOne()等唤醒时,mutex又会被重新锁定,并继续运行
mutex.unlock();
qDebug()<<"-------> 2 <---------";
}
}
thread2.cpp
#include "thread2.h"
#include <QDebug>
thread2::thread2(QObject *parent) :
QThread(parent)
{
}
void thread2::run()
{
qDebug()<<"线程2已激活";
}
运行效果:
(1)按钮点击一次时的调试输出
(3)按钮点击多次时的调试输出
结论:借助网友的说法,在debug里面可以看到线程1的run函数只进入了一次,虽然我们调用了它很多次。也就是说使用waitCondition可以让线程进入休眠而不用退出。