1. 程式人生 > >使用QtConcurrent編寫多執行緒程式(也可以阻塞)

使用QtConcurrent編寫多執行緒程式(也可以阻塞)

版權宣告:本文為博主原創文章,未經博主允許不得轉載。 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
版權宣告:本文為博主原創文章,轉載請附上博文連結!