文章目录
- 开发平台
- 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();
}