版權聲明:本文為博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/Amnes1a/article/details/66470751
Qt在其QtConcurrent命名空間中為我們提供了編寫多線程程序的高級API,使用這個API可以使我們在不使用低級的線程元素,如互斥鎖,讀寫鎖,條件變量或者信號量的情況下編寫出搞笑的多線程程序。並且,使用QtConcurrent編寫的程序能夠自動地根據當前可以使用的處理器核心數調整實際使用的線程數目。這就意味着我們目前所寫的程序即使將來的多核心機器上也能正常運行,並有很好的伸縮性。
QtConcurrent命名空間中包括了用於並行處理的函數式編程API,其中有用於共享內存系統的MapReduce 和 FilterReduce,和用於在GUI程序中管理異步計算的相關類。其中,管理異步計算的幾個類,我們在前面已經說過了,即QFuture,QFutureIterator,QFutureWatcher,QFutureSynchronizer。今天,我們主要來看一下MapReduce和FilterReduce方法。
MapReduce相關方法包括:
QtConcurrent::map():這個函數會將作為參數傳入的函數應用到容器中的每一項,對這些項進行就地修改。
QtConcurrent::mapped():功能類似於map(),只不過它不是在原來的容器中就地修改,而是將修改后的元素放到一個新的容器中返回。
QtConcurrent::mappedReduce():功能類似於mapped(),只不過它會將修改過的每一項再傳入另一個Reduce函數進行簡化,將多個結果按某種要求簡化成一個。
FilterReduce相關方法包括:
QtConcurrent::filter():從容器中刪除那些滿足某個過來條件的項。
QtConcurrent::filtered():功能類似於filter(),只不過它會返回一個包含剩余元素的容器。
QtConcurrent::filteredReduced():功能類似於filtered(),只不過那些剩余的元素會被進一步傳入一個Reduce() 函數,進行簡化。
QtConcurrent命名空間中組合一類函數,就是我們之間講過的run() 函數。
下面,我們分別通過實例還看一下這些函數的使用方法。先來看Map類方法,代碼如下:
#include <QCoreApplication>
#include <QtConcurrent>
#include <QVector>
#include <QDebug>
#include <QFuture>
void testMap(int& num)
{
num += 1;
}
int testMap2(const int& num)
{
return num + 1;
}
void testReduce(int& result, const int& item)
{
result = item > result ? item : result;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QVector<int> vec;
qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
for(int i = 1; i <= 10; i++)
{
vec.push_back(qrand() % 100);
}
qDebug() << "origin: " << vec;
//Map
QFuture<void> f = QtConcurrent::map(vec, testMap);
f.waitForFinished();
qDebug() << "after map: " << vec;
QFuture<int> r = QtConcurrent::mappedReduced(vec, testMap2, testReduce);
qDebug() << "max: " << r.result();
return a.exec();
}
首先,在上面的代碼中,我們聲明了兩個map類函數。testMap()用於QtConcurrent::map(),對容器中的每一項進行就地修改;testMap2()用於QtConcurrent::MappedReduced(),將進行過map的那些元素簡化成一個,在此我們是求map后容器中的最大值。注意testMap()和testMap2()的區別。
上面的代碼實現的功能很簡單。先產生10個隨機數存入vector,然后對該vector應用testMap()方法,將容器中的每一項加1,輸出加1后的結果;然后我們再對加1處理過的容器應用testMap2()和testReduce(),其中testMap2()會對容器中的每一項再加1,然后將結果傳入testReduce()方法,該方法找出當前容器中的最大值。運行結果如下:
下面,我們再來簡單看下Filter類函數,還是先上代碼:
#include <QCoreApplication>
#include <QtConcurrent>
#include <QVector>
#include <QDebug>
#include <QFuture>
void testReduce(int& result, const int& item)
{
result = item > result ? item : result;
}
bool testFilter(const int& item)
{
return item >= 50;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QVector<int> vec;
qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
for(int i = 1; i <= 10; i++)
{
vec.push_back(qrand() % 100);
}
qDebug() << "origin: " << vec;
//Filter
QFuture<void> f = QtConcurrent::filter(vec, testFilter);
f.waitForFinished();
qDebug() << "after filter: " << vec;
QFuture<int> r = QtConcurrent::filteredReduced(vec, testFilter, testReduce);
qDebug() << "max: " << r.result();
return a.exec();
}
實現的功能和上面一下,將產生的隨機數先進行過濾,在找出最大值。運行結果如下:
當然,這里只是簡單的演示一下該命名空間中常用函數的使用方法。大家主要要注意MapFunction、FilterFunction、ReduceFunction的聲明,形式不能錯。
另外,上面演示的這些函數都是QtConcurrent命名空間中的非阻塞函數。其實,在該命名空間中還提供了一系列的阻塞函數。聲明信息如下:
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)
這些函數的使用方式和上面演示的非阻塞函數類似,在此就不一一演示了,大家可以自行測試,或使用上面我給出的例子進行測試。
---------------------
作者:求道玉
來源:CSDN
原文:https://blog.csdn.net/Amnes1a/article/details/66470751
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!