德阳网站建设推广,小程序开发公司哪家正规,WordPress换域名更新,vs如何做网站1. Qt 创建线程的三种方法
1.1 方式一#xff1a;派生于 QThread 派生于 QThread#xff0c;这是 Qt 创建线程最常用的方法#xff0c;重写虚函数 void QThread::run()#xff0c;在 run() 写具体的内容#xff0c;外部通过 start 调用#xff0c;即可执行线程体 run() …1. Qt 创建线程的三种方法
1.1 方式一派生于 QThread 派生于 QThread这是 Qt 创建线程最常用的方法重写虚函数 void QThread::run()在 run() 写具体的内容外部通过 start 调用即可执行线程体 run() 派生于 QThread 的类构造函数属于主线程run() 函数属于子线程可以通过打印线程 id 判断 main.cpp
#include QCoreApplication
#include iostream
#include thread01.hint main(int argc, char *argv[]) {QCoreApplication a(argc, argv);std::cout main thread QThread::currentThreadId() std::endl;Thread01 *th new Thread01();th-start();std::cout main thread end std::endl;return a.exec();
}thread01.h
#pragma once
#include QThreadclass Thread01 : public QThread {Q_OBJECTpublic:Thread01();void run() override;
};thread01.cpp
#include thread01.h
#include QDebugThread01::Thread01() {qDebug() Thread01 construct QThread::currentThreadId();
}void Thread01::run() {qDebug() Thread01 run QThread::currentThreadId();int index 0;while (1) {qDebug() index;QThread::msleep(500);}
}控制台输出
main thread 00004A20
Thread01 construct 0x4a20 // 构造函数属于主线程
Thread01 run 0x4f18 // run() 函数属于子线程
0
main thread end
1
2
3
...1.2 方式二派生于 QRunnable 派生于 QRunnable重写 run() 方法在 run() 方法里处理其它任务调用时需要借助 Qt 线程池 这种新建线程的方法的缺点是不能使用 Qt 的信号与槽机制因为 QRunnable 不是继承自 QObject但这种方法的好处是可以让 QThreadPool 来管理线程QThreadPool 会自动清理新建的 QRunnable 对象 main.cpp
#include QCoreApplication
#include iostream
#include thread02.h
#include QThreadPoolint main(int argc, char *argv[]) {QCoreApplication a(argc, argv);std::cout main thread QThread::currentThreadId() std::endl;Thread02 *th new Thread02();QThreadPool::globalInstance()-start(th);std::cout main thread end std::endl;return a.exec();
}thread02.h
#pragma once
#include QRunnableclass Thread02 : public QRunnable {
public:Thread02();~Thread02();void run() override;
};thread02.cpp
#include thread02.h
#include QThread
#include QDebugThread02::Thread02() {qDebug() Thread02 construct QThread::currentThreadId();
}Thread02::~Thread02() {qDebug() Thread02 xigou func;
}void Thread02::run() {qDebug() Thread02 run QThread::currentThreadId();
}1.3 moveToThread 派生于 QObject使用 moveToThread 方法 将 QThread 对象作为私有成员在构造函数里 moveToThread然后启动线程 ch71_moveToThread.h
#pragma once#include QtWidgets/QWidget
#include ui_ch71_moveToThread.h
#include Thread03.hclass ch71_moveToThread : public QWidget {Q_OBJECTpublic:ch71_moveToThread(QWidget *parent nullptr);~ch71_moveToThread();private slots:void on_pushButton_clicked();signals:void sig_fun();private:Ui::ch71_moveToThreadClass ui;Thread03* m_pTh03 nullptr;
};ch71_moveToThread.cpp
#include ch71_moveToThread.h
#include QDebugch71_moveToThread::ch71_moveToThread(QWidget *parent) : QWidget(parent) {ui.setupUi(this);qDebug() main construct QThread::currentThreadId();m_pTh03 new Thread03();connect(this, ch71_moveToThread::sig_fun, m_pTh03, Thread03::fun);
}ch71_moveToThread::~ch71_moveToThread() {}void ch71_moveToThread::on_pushButton_clicked() {emit sig_fun();
}Thread03.h
#pragma once
#include QObject
#include QThreadclass Thread03 : public QObject {
public:Thread03();public slots:void fun();private:QThread m_th;
};Thread03.cpp
#include Thread03.h
#include QDebugThread03::Thread03() {this-moveToThread(m_th);m_th.start();qDebug() Thread03 construct QThread::currentThreadId();
}void Thread03::fun() {qDebug() Thread03 fun QThread::currentThreadId();int index 0;while (1) {qDebug() index;QThread::msleep(300);}
}控制台输出
main construct 0x11f0
Thread03 construct 0x11f0
// 点击按钮后
Thread03 fun 0x2b74
0
1
2
3
...2. Qt 并发
2.1 QtConcurrent 基本用法
ch72_concurrent.h
#pragma once#include QtWidgets/QWidget
#include ui_ch72_concurrent.hclass ch72_concurrent : public QWidget {Q_OBJECTpublic:ch72_concurrent(QWidget *parent nullptr);~ch72_concurrent();int timeTask();private slots:void on_pushButton_clicked();private:Ui::ch72_concurrentClass ui;
};ch72_concurrent.cpp
#include ch72_concurrent.h
#include QThread
#include QDebug
#include QtConcurrent
#include QFuturech72_concurrent::ch72_concurrent(QWidget *parent) : QWidget(parent) {ui.setupUi(this);
}ch72_concurrent::~ch72_concurrent() {}int ch72_concurrent::timeTask() {int num 0;for (int i 0; i 1000000; i) {num;qDebug() num;}return num;
}void ch72_concurrent::on_pushButton_clicked() {//timeTask();QFutureint ft QtConcurrent::run(this, ch72_concurrent::timeTask);while (!ft.isFinished()) {// 当 future 未完成时让 cpu 去做别的事情QApplication::processEvents(QEventLoop::AllEvents, 30);}
}2.2 QtConcurrent run() 参数说明
QtConcurrent::run 函数参数可以是全局函数也可以是类成员函数ch73_concurrent.cpp
#include ch73_concurrent.h
#include QDebug
#include QtConcurrent
#include QFuturech73_concurrent::ch73_concurrent(QWidget *parent) : QWidget(parent) {ui.setupUi(this);
}ch73_concurrent::~ch73_concurrent() {}int ch73_concurrent::timeTask(int num1, int num2) {//int num 0;for (int i 0; i 1000000; i) {num1;num2;qDebug() num1;qDebug() num2;}return num1 num2;
}int gTimeTask(int num1, int num2) {//int num 0;for (int i 0; i 1000000; i) {num1;num2;qDebug() num1;qDebug() num2;}return num1 num2;
}void ch73_concurrent::on_pushButton_clicked() {//timeTask();int num1 0;int num2 0;//QFutureint ft QtConcurrent::run(this, ch73_concurrent::timeTask, num1, num2);QFutureint ft QtConcurrent::run(gTimeTask, num1, num2);while (!ft.isFinished()) {QApplication::processEvents(QEventLoop::AllEvents, 30);}
}2.3 获取 QtConcurrent 的返回值
获取 QtConcurrent 的结果需要使用 QFutureWatcher 类链接它的信号 finished然后给 watcher 设置 future当监控到 future 执行结束后可以获取它的执行结果调用的是 result() 函数ch74.cpp
#include ch74.h
#include QDebug
#include QtConcurrent
#include QFuture
#include QFutureWatcherch74::ch74(QWidget *parent) : QWidget(parent) {ui.setupUi(this);
}ch74::~ch74() {}int ch74::timeTask(int num1, int num2) {for (int i 0; i 1000; i) {num1;num2;qDebug() num1;qDebug() num2;}return num1 num2;
}void ch74::on_pushButton_clicked() {int num1 0;int num2 0;QFutureWatcherint* fw new QFutureWatcherint;connect(fw, QFutureWatcherint::finished, []{qDebug() QFutureWatcher finished;qDebug() result fw-result();});QFutureint ft QtConcurrent::run(this, ch74::timeTask, num1, num2);fw-setFuture(ft);while (!ft.isFinished()) {QApplication::processEvents(QEventLoop::AllEvents, 30);}
}3. C 其他线程技术
pthreadlinux 线程win32-pthread obs 的线程全部使用了 win32-pthreadwindows thread 类MFC thread类booststd::thread推荐用这个基于语言级别的跨平台 C 线程