文章目录
- 开发平台
- QThread 类 + moveToThread
- QtConcurrent::run + QFutureWatcher
- QThreadPool + QRunnable
开发平台
项目 | 说明 |
---|---|
OS | win10 x64 |
Qt | 6.6 |
compiler | msvc2022 |
构建工具 | cmake |
QThread 类 + moveToThread
写一个简单的例子吧,比较容易理解,方便入门. 也可以看出这种方式,对于线程的开销会比较大,但可以自己设置外部的 线程对象, 以达到复用或者减少开销的目的,但不如用线程池来的直接
#include <QApplication>
#include <QThread>
#include <QtConcurrent>class MyWork : public QObject
{Q_OBJECT
public:MyWork() {this->moveToThread(&thread);thread.start();connect(this,&MyWork::startSignal,this,&MyWork::run);connect(&thread,&QThread::finished,this,[]{qDebug() << "Thread::finished";});connect(&thread,&QThread::destroyed,qApp,[]{qDebug() << "Thread::destroyed";});}~MyWork(){if(thread.isRunning())thread.terminate();qDebug() << "~MyWork()";}void start() {emit startSignal();}void stop(){running = false;if(thread.isRunning())thread.quit();}void run() {static int i = 0;while(running) {QThread::msleep(1000);qDebug() << i++ << ":" << QThread::currentThreadId();}}signals:void startSignal();void stopSignal();private:QThread thread;bool running = true;
};int main(int argc, char** argv) {QApplication a(argc,argv);qDebug() << QThread::currentThreadId();MyWork mw;mw.start();QTimer::singleShot(3000,[&mw]{mw.stop();});QTimer::singleShot(4000,qApp, SLOT(quit()) );return a.exec();
}#include "main.moc" // 这一句很重要,因为是写在main.cpp里面的,注意编译器的输出提示
QtConcurrent::run + QFutureWatcher
在 Qt 6 中, QtConcurrent::run 的函数原型中,已经没有 对象指针,即调用成员函数的时候, 要么使用 Lambda 对象 ,要么使用 std::bind 方法
这种方式感觉比较方便,但实际应用起来没有那么美好,属于后期为了改善效率,匆忙添加的手段
#include <QApplication>
#include <QThread>
#include <QTimer>
#include <qDebug>
#include <QtConcurrent>class MyWork {QFutureWatcher<void> w;bool isRun = false;
public:MyWork() {qDebug() << " MyWork()";QObject::connect(&w, &QFutureWatcher<void>::finished, &w, []{qDebug() << "QFutureWatcher<void>::finished";});}~MyWork(){qDebug() << " ~MyWork()";}void start() {isRun = true;auto fun = std::bind(&MyWork::run, this );auto ret = QtConcurrent::run( fun );// auto ret = QtConcurrent::run([this]{// run();// });w.setFuture(ret);}void stop(){isRun = false;}void run() {int i = 0;while(isRun) {QThread::msleep(1000);qDebug() << i++ << ":" << QThread::currentThreadId();}}
};
int main(int argc, char** argv) {QApplication a(argc,argv);qDebug() << ":" << QThread::currentThreadId();MyWork mw;mw.start();QTimer::singleShot(3000, [&mw]{mw.stop();});QTimer::singleShot(5000, []{qDebug() << "qApp->quit();";qApp->quit();});return a.exec();
}
QThreadPool + QRunnable
继承 QRunnable, 重写 run
QThreadPool::globalInstance()->start(this);
清晰明了, QThreadPool 提供了 线程的管理,不需要自己去写一个管理器
#include <QApplication>
#include <QtConcurrent>class MyWork :public QRunnable {bool isRun = false;
public:MyWork() {// setAutoDelete(false);qDebug() << " MyWork()";}~MyWork(){qDebug() << " ~MyWork()";}void start(){isRun = true;QThreadPool::globalInstance()->start(this);}void stop(){isRun = false;}void run() {int i = 0;while(isRun) {QThread::msleep(1000);qDebug() << i++ << ":" << QThread::currentThreadId();}}
};
int main(int argc, char** argv) {QApplication a(argc,argv);qDebug() << ":" << QThread::currentThreadId();// MyWork mw ;// mw.start();MyWork *mw = new MyWork;mw->start();QTimer::singleShot(3000, [mw]{mw->stop();});QTimer::singleShot(6000, []{qApp->quit();});return a.exec();
}