QtConcurrent
QFuture
QFuture 是 Qt 框架中用于表示異步計算結(jié)果的類蛾派。它是 Qt Concurrent 模塊的一部分,通常與多線程編程結(jié)合使用,用于管理和獲取異步任務(wù)的結(jié)果鸵熟。QFuture 提供了一種方便的方式來處理并行任務(wù)亮蒋,而不需要直接管理線程的創(chuàng)建和同步扣典。
QFutureWatcher
QFutureWatcher提供了QFuture的信息和通知。
測試代碼
#include <QtConcurrent>
#include <QFutureWatcher>
#include <QDebug>
#include <QCoreApplication>
#include <QThread>
void task() {
qDebug() << "Task is running...";
QThread::sleep(2); // 模擬耗時操作
qDebug() << "Task finished.";
}
int main(int argc, char *argv[]) {
QCoreApplication app(argc, argv);
// 創(chuàng)建一個任務(wù)并運行
QFuture<void> future = QtConcurrent::run(task);
// 等待任務(wù)完成
future.waitForFinished();
// 創(chuàng)建 QFutureWatcher
QFutureWatcher<void> watcher;
// 連接 finished 信號
QObject::connect(&watcher, &QFutureWatcher<void>::finished, []() {
qDebug() << "QFutureWatcher: Task finished signal received.";
});
// 設(shè)置已經(jīng)完成的 QFuture
qDebug() << "Setting future to QFutureWatcher...";
watcher.setFuture(future);
qDebug() << "Main thread continues running.";
return app.exec();
}
運行結(jié)果:
Task is running...
Task finished.
Setting future to QFutureWatcher...
Main thread continues running.
QFutureWatcher: Task finished signal received.
關(guān)鍵點
- 當 QFuture 已經(jīng)運行結(jié)束后宛蚓,再調(diào)用 QFutureWatcher::setFuture()激捏,仍然會觸發(fā) finished 信號。但不是立即觸發(fā)凄吏。
setFuture()源碼
//QFutureWatcher::setFuture源碼調(diào)用:
QFutureWatcher::setFuture()
->QFutureWatcherBase::connectOutputInterface();
->futureInterface().d->connectOutputInterface(d_func()) //futureInterface().d即QFuture內(nèi)部指針远舅。
->QFutureCallOutInterface->postCallOutEvent(finished)//判斷QFuture已經(jīng)結(jié)束后。
繼續(xù)查找到QFutureWatcherBasePrivate::postCallOutEvent();
void QFutureWatcherBasePrivate::postCallOutEvent(const QFutureCallOutEvent &callOutEvent)
{
Q_Q(QFutureWatcherBase);
if (callOutEvent.callOutType == QFutureCallOutEvent::ResultsReady) {
if (pendingResultsReady.fetchAndAddRelaxed(1) >= maximumPendingResultsReady)
q->futureInterface().d->internal_setThrottled(true);
}
QCoreApplication::postEvent(q, callOutEvent.clone());
}
可以看到最終是通過QCoreApplication::postEvent()發(fā)送了一個事件痕钢。那么只有下次事件循環(huán)時图柏,才會發(fā)送出finished信號。