博客地址已更改,文章數量較多不便批量修改,若想訪問源文請到 coologic博客 查閱,網址:www.coologic.cn
如本文記錄地址為 techieliang.com/A/B/C/ 請改為 www.coologic.cn/A/B/C/ 即可查閱
版權聲明:若無來源注明, Techie亮博客文章均為原創。 轉載請以鏈接形式標明本文標題和地址:
本文標題:Qt多線程-QtConcurrent並行運算高級API 本文地址: http://techieliang.com/2017/12/608/
1. 介紹
Qt除了提供基本的QThread實現多線程,並提供QThreadPool實現線程池以外,還提供了QtConcurrent模塊用於並行計算。
使用此類需要在pro文件增加QT += concurrent
1.1. API
- void blockingFilter(Sequence &sequence, FilterFunction filterFunction)
- Sequence blockingFiltered(const Sequence &sequence, FilterFunction filterFunction)
- Sequence blockingFiltered(ConstIterator begin, ConstIterator end, FilterFunction filterFunction)
- T blockingFilteredReduced(const Sequence &sequence, FilterFunction filterFunction, ReduceFunction reduceFunction, QtConcurrent::ReduceOptions reduceOptions = UnorderedReduce | SequentialReduce)
- T blockingFilteredReduced(ConstIterator begin, ConstIterator end, FilterFunction filterFunction, ReduceFunction reduceFunction, QtConcurrent::ReduceOptions reduceOptions = UnorderedReduce | SequentialReduce)
- void blockingMap(Sequence &sequence, MapFunction function)
- void blockingMap(Iterator begin, Iterator end, MapFunction function)
- T blockingMapped(const Sequence &sequence, MapFunction function)
- T blockingMapped(ConstIterator begin, ConstIterator end, MapFunction function)
- T blockingMappedReduced(const Sequence &sequence, MapFunction mapFunction, ReduceFunction reduceFunction, QtConcurrent::ReduceOptions reduceOptions = UnorderedReduce | SequentialReduce)
- T blockingMappedReduced(ConstIterator begin, ConstIterator end, MapFunction mapFunction, ReduceFunction reduceFunction, QtConcurrent::ReduceOptions reduceOptions = UnorderedReduce | SequentialReduce)
- QFuture<void> filter(Sequence &sequence, FilterFunction filterFunction)
- QFuture<T> filtered(const Sequence &sequence, FilterFunction filterFunction)
- QFuture<T> filtered(ConstIterator begin, ConstIterator end, FilterFunction filterFunction)
- QFuture<T> filteredReduced(const Sequence &sequence, FilterFunction filterFunction, ReduceFunction reduceFunction, QtConcurrent::ReduceOptions reduceOptions = UnorderedReduce | SequentialReduce)
- QFuture<T> filteredReduced(ConstIterator begin, ConstIterator end, FilterFunction filterFunction, ReduceFunction reduceFunction, QtConcurrent::ReduceOptions reduceOptions = UnorderedReduce | SequentialReduce)
- QFuture<void> map(Sequence &sequence, MapFunction function)
- QFuture<void> map(Iterator begin, Iterator end, MapFunction function)
- QFuture<T> mapped(const Sequence &sequence, MapFunction function)
- QFuture<T> mapped(ConstIterator begin, ConstIterator end, MapFunction function)
- QFuture<T> mappedReduced(const Sequence &sequence, MapFunction mapFunction, ReduceFunction reduceFunction, QtConcurrent::ReduceOptions reduceOptions = UnorderedReduce | SequentialReduce)
- QFuture<T> mappedReduced(ConstIterator begin, ConstIterator end, MapFunction mapFunction, ReduceFunction reduceFunction, QtConcurrent::ReduceOptions reduceOptions = UnorderedReduce | SequentialReduce)
- QFuture<T> run(Function function, ...)
- QFuture<T> run(QThreadPool *pool, Function function, ...)
很多都是重載的,主要函數如下:
- Concurrent Map and Map-Reduce
- QtConcurrent::map() applies a function to every item in a container, modifying the items in-place.
- –這個函數會將作為參數傳入的函數應用到容器中的每一項,對這些項進行直接修改,會修改傳入變量內容。
- QtConcurrent::mapped() is like map(), except that it returns a new container with the modifications.
- –功能類似於map(),只不過它不是直接修改原始容器,而是將修改后的元素放到一個新的容器中並作為返回值返回。
- QtConcurrent::mappedReduced() is like mapped(), except that the modified results are reduced or folded into a single result.
- –功能類似於mapped(),首先執行mapped的操作,然后傳入一個Reduce函數進行簡化,最終返回唯一一個元素,此操作不會修改原始容器。
- Concurrent Filter and Filter-Reduce
- QtConcurrent::filter() removes all items from a container based on the result of a filter function.
- –從容器中刪除那些滿足某個過來條件的項。
- QtConcurrent::filtered() is like filter(), except that it returns a new container with the filtered results.
- –功能類似於filter(),只不過它會返回一個包含剩余元素的容器。
- QtConcurrent::filteredReduced() is like filtered(), except that the filtered results are reduced or folded into a single result.
- –功能類似於filtered(),后續進行reduce操作。
- Concurrent Run
- QtConcurrent::run() runs a function in another thread.
- –用另一個進程運行一個函數
- QFuture represents the result of an asynchronous computation.
- — 獲取一步計算結果
- QFutureIterator allows iterating through results available via QFuture.
- –通過使用QFuture允許遍歷結果
- QFutureWatcher allows monitoring a QFuture using signals-and-slots.
- — 利用信號槽監視QFuture
- QFutureSynchronizer is a convenience class that automatically synchronizes several QFutures.
- –自動同步多個futures
2. QtConcurrent::map
map的范例:http://doc.qt.io/qt-5/qtconcurrent-map-example.html
map詳細介紹:http://doc.qt.io/qt-5/qtconcurrentmap.html
- #include <QCoreApplication>
- #include <QtConcurrent>
- #include <QVector>
- #include <QDebug>
- #include <QFuture>
- void MapFunction(int& num) {
- num += 1;
- }
- int mappedReducedFunction(const int& num) {
- return num + 1;
- }
- void ReduceFunction(int& result, const int& item) {
- int t_r = result;
- result = item > result ? item : result;
- qDebug()<<t_r<<result<<item;
- }
- int main(int argc, char *argv[]) {
- QCoreApplication a(argc, argv);
- QVector<int> testVactor;
- for(int i = 1; i <= 3; i++) {
- testVactor.push_back(i);
- }
- for(int i = 1; i <= 3; i++) {
- testVactor.push_back(10-i);
- }
- qDebug() << "start m:" << testVactor;
- QFuture<void> f = QtConcurrent::map(testVactor, MapFunction);
- f.waitForFinished();
- qDebug() << "map result:" << testVactor;//map直接修改源數據
- QFuture<int> r = QtConcurrent::mappedReduced(testVactor, mappedReducedFunction, ReduceFunction);
- qDebug() << "mappedReduced result:" << r.result();
- return 0;
- }
注意幾個函數的聲明形式,不可有差距。結果
- start m: QVector(1, 2, 3, 9, 8, 7)
- map result: QVector(2, 3, 4, 10, 9, 8)
- 0 3 3
- 3 4 4
- 4 5 5
- 5 11 11
- 11 11 10
- 11 11 9
- mappedReduced result: 11
結果示意很明顯,reduced最終表留的是等於函數result參數值的項
3. QtConcurrent::filter
filter詳細介紹:http://doc.qt.io/qt-5/qtconcurrentfilter.html
- #include <QCoreApplication>
- #include <QtConcurrent>
- #include <QList>
- #include <QDebug>
- #include <QFuture>
- bool filterFunction(const int& num) {
- return (num > 5);
- }
- void ReduceFunction(int& result, const int& item) {
- int t_r = result;
- result = item > result ? item : result;
- qDebug()<<t_r<<result<<item;
- }
- int main(int argc, char *argv[]) {
- QCoreApplication a(argc, argv);
- QList<int> testVactor;
- for(int i = 1; i <= 3; i++) {
- testVactor.push_back(i);
- }
- for(int i = 1; i <= 3; i++) {
- testVactor.push_back(10-i);
- }
- qDebug() << "start m:" << testVactor;
- QFuture<void> f = QtConcurrent::filter(testVactor, filterFunction);
- f.waitForFinished();
- qDebug() << "map result:" << testVactor;//map直接修改源數據
- QFuture<int> r = QtConcurrent::filteredReduced(testVactor, filterFunction, ReduceFunction);
- qDebug() << "mappedReduced result:" << r.result();
- return 0;
- }
注意幾個函數的聲明形式,不可有差距。filter函數要返回bool類型,用於判斷是否過濾此元素
結果:
- start m: (1, 2, 3, 9, 8, 7)
- map result: (9, 8, 7)
- 0 9 9
- 9 9 8
- 9 9 7
- mappedReduced result: 9
4. QtConcurrent::run
感覺run用起來很舒服,因為他沒有對運行函數頭做限制,可以是任意數量的任意類型參數。
run的詳細幫助:http://doc.qt.io/qt-5/qtconcurrentrun.html,也可以看看本機的qtconcurrentrun.h文件,可以看到里面有很多的run的重載函數
下面給出最基本的使用
- #include <QCoreApplication>
- #include <QtConcurrent>
- #include <QList>
- #include <QDebug>
- #include <QThread>
- void function(const QList<int>& param1, const int& param2, Qt::HANDLE main_id) {
- qDebug()<<"function param:"<<param1<<param2<<main_id;
- qDebug()<<"function thread id:" <<QThread::currentThreadId();
- }
- int main(int argc, char *argv[]) {
- QCoreApplication a(argc, argv);
- QList<int> testVactor;
- for(int i = 1; i <= 3; i++) {
- testVactor.push_back(i);
- }
- qDebug() << "main thread id:" << QThread::currentThreadId();
- QFuture<void> f = QtConcurrent::run(function,testVactor,666,QThread::currentThreadId());
- f.waitForFinished();//要等待,否則線程沒運行完程序結束會出錯
- return 0;
- }
結果
- main thread id: 0x2a10
- function param: (1, 2, 3) 666 0x2a10
- function thread id: 0x2344
4.1. 其他使用方式-指定線程池
有時候希望運行的函數在全局線程池或者局部線程池運行,而不是有qt托管處理,可以進行如下方式調用:
- extern void aFunction();
- QThreadPool pool;
- QFuture<void> future = QtConcurrent::run(&pool, aFunction);
5. 阻塞QtConcurrent
上述所有函數都是非阻塞的,所以在return 0前都有waitForFinished,qt同樣提供了阻塞函數
見最開始API幫助介紹連接,可以看到相關接口
- void blockingFilter(Sequence &sequence, FilterFunction filterFunction)
- Sequence blockingFiltered(const Sequence &sequence, FilterFunction filterFunction)
- Sequence blockingFiltered(ConstIterator begin, ConstIterator end, FilterFunction filterFunction)
- T blockingFilteredReduced(const Sequence &sequence, FilterFunction filterFunction, ReduceFunction reduceFunction, QtConcurrent::ReduceOptions reduceOptions = UnorderedReduce | SequentialReduce)
- T blockingFilteredReduced(ConstIterator begin, ConstIterator end, FilterFunction filterFunction, ReduceFunction reduceFunction, QtConcurrent::ReduceOptions reduceOptions = UnorderedReduce | SequentialReduce)
- void blockingMap(Sequence &sequence, MapFunction function)
- void blockingMap(Iterator begin, Iterator end, MapFunction function)
- T blockingMapped(const Sequence &sequence, MapFunction function)
- T blockingMapped(ConstIterator begin, ConstIterator end, MapFunction function)
- T blockingMappedReduced(const Sequence &sequence, MapFunction mapFunction, ReduceFunction reduceFunction, QtConcurrent::ReduceOptions reduceOptions = UnorderedReduce | SequentialReduce)
- T blockingMappedReduced(ConstIterator begin, ConstIterator end, MapFunction mapFunction, ReduceFunction reduceFunction, QtConcurrent::ReduceOptions reduceOptions = UnorderedReduce | SequentialReduce)
可以看到對應函數的介紹都有:
Note: This function will block until all items in the sequence have been processed.
使用方式近似,不提供示例了。