笔记-Qt多线程
QThread-线程
-
实现方式1, 不推荐
继承QThread对象, 然后重新实现虚函数QThread::runclass WorkerThread : public QThread { Q_OBJECT void run() override { QString result; /* ... here is the expensive or blocking operation ... */ emit resultReady(result); } signals: void resultReady(const QString &s); }; void MyObject::startWorkInAThread() { WorkerThread *workerThread = new WorkerThread(this); connect(workerThread, &WorkerThread::resultReady, this, &MyObject::handleResults); connect(workerThread, &WorkerThread::finished, workerThread, &QObject::deleteLater); workerThread->start(); }
-
实现方式2, 推荐
对于继承Object的对象, 通过QObject::moveToThread(QThread *targetThread)改变对象和它的子对象的线程关联性, 再利用信号槽机制, 将定义在对象中成员函数放在targetThread中运行;
需要注意, 如果对象有父对象, 着无法移动成功.class Worker : public QObject { Q_OBJECT public slots: void doWork(const QString ¶meter) { QString result; /* ... here is the expensive or blocking operation ... */ emit resultReady(result); } signals: void resultReady(const QString &result); }; class Controller : public QObject { Q_OBJECT QThread workerThread; public: Controller() { Worker *worker = new Worker; worker->moveToThread(&workerThread); connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater); connect(this, &Controller::operate, worker, &Worker::doWork); connect(worker, &Worker::resultReady, this, &Controller::handleResults); workerThread.start(); } ~Controller() { workerThread.quit(); workerThread.wait(); } public slots: void handleResults(const QString &); signals: void operate(const QString &); };
QThreadPool-线程池
qt中线程池需要注意添加到线程池的对象必须继承至QRunnable对象, 在实现QRunnable::run, 线程池会分配线程去执行QRunnable::run函数, 对于QRunnable对象的生命周期问题, 可以通过void QRunnable::setAutoDelete(bool autoDelete)设置autoDelete=true来规避;
class HelloWorldTask : public QRunnable
{
void run()
{
qDebug() << "Hello world from thread" << QThread::currentThread();
}
}
HelloWorldTask *hello = new HelloWorldTask();
// QThreadPool takes ownership and deletes 'hello' automatically
QThreadPool::globalInstance()->start(hello);
QtConcurrent-并发任务
QtConcurrent其实就是将函数添加到QThreadPool::globalInstance()中, 可以当作是QThreadPool+QRunable的简化操作吧
QFuture<T> QtConcurrent::run(Function function, ...)
相当于: QtConcurrent::run(QThreadPool::globalInstance(), function, ...);
QFuture<T> QtConcurrent::run(QThreadPool *pool, Function function, ...)
QtConcurrent::run([]() {
qDebug() << "current thread id=" << QThread::currentThreadId() << " time="
<< QDateTime::currentDateTime().toString("HH:mm:ss:zzz");
QThread::sleep(1);
});