一、类型成员
1、enum QtConcurrent::ReduceOption:此枚举指定将 map 或 filter 函数的结果传递给 reduce 函数的顺序。
- UnorderedReduce:任意顺序。
- OrderedReduce:按照原始序列的顺序进行的。
- SequentialReduce:一次只有一个线程会进入reduce功能。
二、成员函数
2.1、总结
此命名空间的函数可以分成3类:
运行时阻塞的(处理容器中的数据)
- blockingFilter:为列表中每个项目调用过滤器函数(返回bool类型),过滤器函数返回false的项目从列表中删除。
- blockingFiltered:与1类似,不修改原列表,返回新列表。
- blockingFilteredReduced:为列表中每个项目调用过滤器函数(返回bool类型),将过滤器函数返回true的项目传递给 reduceFunction。
- blockingMap:按顺序为列表中每个项目调用一次函数。
- blockingMapped:按顺序为列表中每个项目调用一次函数(函数必须要有返回值)。
- blockingMappedReduced:按顺序为每个项目调用一次函数(函数要有返回值)。每个返回值传递给 reduceFunction。
运行时不阻塞的(处理容器中的数据)
- filter:与 blockingFilter 对应相似。
- filtered:与 blockingFiltered 对应相似。
- filteredReduced:与 blockingFilteredReduced 对应相似。
- map:与 blockingMap 对应相似。
- mapped:与 blockingMapped 对应相似。
- mappedReduced:与 blockingMappedReduced 对应相似。
在另一个线程中运行一个函数
- run:在单独的线程中运行函数。
2.2、函数
1、template <typename Sequence, typename KeepFunctor> void blockingFilter(Sequence &sequence, KeepFunctor filterFunction)
按顺序为每个项目调用 filterFunction 一次。filterFunction 返回值为需为 bool 类型。如果 filterFunction 返回 true 项目保持顺序,否则该项目将从序列中删除。
注意:此函数将阻塞,直到序列中的所有项目都已处理完毕。
bool hasA(const QString & str)
{
qDebug()<<QThread::currentThreadId();
return str.contains('A');
}
int main(int argc, char *argv[])
{
QList<QString> list;
list << "ABC"<<"CDE"<<"GHI";
QtConcurrent::blockingFilter(list,hasA);
qDebug()<<list;
}
2、template <typename Sequence, typename KeepFunctor> Sequence blockingFiltered(const Sequence &sequence, KeepFunctor filterFunction)
与上面类似,不过不修改原列表,返回新的列表。
QList<QString> list;
list << "ABC"<<"CDE"<<"GHI";
auto result = QtConcurrent::blockingFiltered(list,hasA);
qDebug()<<list;
qDebug()<<result;
3、template <typename OutputSequence, typename Iterator, typename KeepFunctor> OutputSequence blockingFiltered(Iterator begin, Iterator end, KeepFunctor filterFunction)
重载函数。从头到尾为每个项目调用 filterFunction 一次,并返回一个新的保留项目序列。如果 filterFunction 返回 true,则将项目的副本放入新的 Sequence。 否则,该项目将不会出现在新序列中。
注意:此函数将阻塞,直到迭代器到达正在处理的序列的末尾。
QList<QString> list;
list << "ABC"<<"CDE"<<"GHI"<<"CBA";
auto result = QtConcurrent::blockingFiltered<QStringList>(list.begin(),list.end(),hasA);
qDebug()<<list;
qDebug()<<result;
QList<QString> list;
list << "ABC"<<"CDE"<<"GHI"<<"CBA";
auto result = QtConcurrent::blockingFiltered<QString>(list.begin(),list.end(),hasA);
qDebug()<<list;
qDebug()<<result;
自定义存放结果的对象类型。
4、template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor> ResultType blockingFilteredReduced(const Sequence &sequence, KeepFunctor filterFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions = ReduceOptions(UnorderedReduce | SequentialReduce))
按顺序为每个项目调用 filterFunction 一次。如果 filterFunction 为某个项目返回 true,则该项目将被传递给 reduceFunction。
请注意,虽然 filterFunction 是并发调用的,但 reduceFunction 会在同一个线程调用。如果 reduceOptions 是 UnorderedReduce,则调用 reduceFunction 的顺序是未定义的。 如果reduceOptions 为 OrderedReduce,则reduceFunction 将按照原始序列的顺序调用。
注意:此函数将阻塞,直到序列中的所有项目都已处理完毕。
bool IsEvenNumber(int i)
{
qDebug()<<"IsEvenNumber()函数线程Id:"<<QThread::currentThreadId();
return i % 2 == 0;
}
void sum(int& result ,int i)
{
qDebug()<<"result = "<<result <<"i = "<<i<<"线程Id:"<<QThread::currentThreadId();
result = i*100;
}
int main(int argc, char *argv[])
{
QList<int> list;
for (int i = 1;i < 12;++i)
{
list << i;
}
auto result = QtConcurrent::blockingFilteredReduced(list,IsEvenNumber,sum,QtConcurrent::UnorderedReduce);
qDebug()<<"list中双数和为:"<<result;
}
auto result = QtConcurrent::blockingFilteredReduced(list,IsEvenNumber,sum,QtConcurrent::OrderedReduce);
5、template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor> ResultType blockingFilteredReduced(Iterator begin, Iterator end, KeepFunctor filterFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions = ReduceOptions(UnorderedReduce | SequentialReduce))
重载函数。
auto result = QtConcurrent::blockingFilteredReduced(list.begin(),list.end(),IsEvenNumber,sum,QtConcurrent::UnorderedReduce);
6、template <typename Sequence, typename MapFunctor> void blockingMap(Sequence &sequence, MapFunctor function)
按顺序为每个项目调用一次function。该函数传递的是项目的引用,因此对项目所做的任何修改都将按顺序的。
注意:此函数将阻塞,直到序列中的所有项目都已处理完毕。
void add(int & i)
{
++i;
}
int main(int argc, char *argv[])
{
QList<int> list;
for (int i = 1;i < 12;++i)
{
list << i;
}
QtConcurrent::blockingMap(list,add);
qDebug()<<list;
}
7、template <typename Iterator, typename MapFunctor> void blockingMap(Iterator begin, Iterator end, MapFunctor function)
重载函数。
8、template <typename OutputSequence, typename InputSequence, typename MapFunctor> OutputSequence blockingMapped(const InputSequence &sequence, MapFunctor function)
按顺序为每个项目调用一次函数,并返回一个包含结果的 OutputSequence。结果的类型将与 MapFunctor 返回的类型相匹配。(注意:函数要有返回值)
注意:此函数将阻塞,直到序列中的所有项目都已处理完毕。
int add2(int i)
{
return ++i;
}
int main(int argc, char *argv[])
{
QList<int> list;
for (int i = 1;i < 12;++i)
{
list << i;
}
auto result = QtConcurrent::blockingMapped(list,add2);
qDebug()<<list;
qDebug()<<result;
}
9、template <typename Sequence, typename Iterator, typename MapFunctor> Sequence blockingMapped(Iterator begin, Iterator end, MapFunctor function)
重载函数。
auto result = QtConcurrent::blockingMapped<QList<int>>(list.begin(),list.end(),add2);
qDebug()<<list;
qDebug()<<result;
10、template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor> ResultType blockingMappedReduced(const Sequence &sequence, MapFunctor mapFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions = ReduceOptions(UnorderedReduce | SequentialReduce))
按顺序为每个项目调用一次 mapFunction。 每个 mapFunction 的返回值传递给 reduceFunction。
请注意,虽然 mapFunction 是并发调用的,但一次只有一个线程会调用 reduceFunction。调用reduceFunction 的顺序由reduceOptions 决定。
注意:此函数将阻塞,直到序列中的所有项目都已处理完毕。
int multiplication(int i)
{
qDebug()<<"multiplication()函数线程Id:"<<QThread::currentThreadId();
return i * 10;
}
void sum(int& result ,int i)
{
qDebug()<<"result = "<<result <<"i = "<<i<<"线程Id:"<<QThread::currentThreadId();
result += i;
}
int main(int argc, char *argv[])
{
QList<int> list;
for (int i = 1;i < 12;++i)
{
list << i;
}
auto result = QtConcurrent::blockingMappedReduced(list,multiplication,sum,QtConcurrent::SequentialReduce);
qDebug()<<list;
qDebug()<<result;
}
11、template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor> ResultType blockingMappedReduced(Iterator begin, Iterator end, MapFunctor mapFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions = QtConcurrent::ReduceOptions(QtConcurrent::UnorderedReduce | QtConcurrent::SequentialReduce))
重载函数。
12、template <typename Sequence, typename KeepFunctor> QFuture<void> filter(Sequence &sequence, KeepFunctor filterFunction)
按顺序为每个项目调用一次 filterFunction 。如果 filterFunction 返回 true,则项目保持顺序;否则,该项目将从序列中删除。
int main(int argc, char *argv[])
{
QList<int> list;
for (int i = 1;i < 12;++i)
{
list << i;
}
QtConcurrent::filter(list,[](const int & i)
{
qDebug()<<QThread::currentThreadId();
return i % 3 == 0;
});
QThread::msleep(1000);
qDebug()<<list;
}
13、template <typename Sequence, typename KeepFunctor> QFuture<typename Sequence::value_type> filtered(const Sequence &sequence, KeepFunctor filterFunction)
与上面类似,但返回一个新的保留项目序列。
QList<int> list;
for (int i = 1;i < 12;++i)
{
list << i;
}
auto result = QtConcurrent::filtered<QList<int>>(list,[](const int & i)
{
return i % 3 == 0;
});
QThread::msleep(1000);
qDebug()<<list;
qDebug()<<result.results();
14、template <typename Iterator, typename KeepFunctor> QFuture<typename qValueType<Iterator>::value_type> filtered(Iterator begin, Iterator end, KeepFunctor filterFunction)
重载函数。
QList<int> list;
for (int i = 1;i < 12;++i)
{
list << i;
}
auto result = QtConcurrent::filtered(list.begin(),list.end(),[](const int & i)
{
return i % 3 == 0;
});
QThread::msleep(1000);
qDebug()<<list;
qDebug()<<result.results();
15、template <typename ResultType, typename Sequence, typename KeepFunctor, typename ReduceFunctor> QFuture<ResultType> filteredReduced(const Sequence &sequence, KeepFunctor filterFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions = ReduceOptions(UnorderedReduce | SequentialReduce))
按顺序为每个项目调用 filterFunction 一次。 如果 filterFunction 为某个项目返回 true,则该项目将被传递给 reduceFunction。
请注意,虽然 filterFunction 是并发调用的,但一次只有一个线程会调用 reduceFunction。
如果 reduceOptions 是 UnorderedReduce,则调用 reduceFunction 的顺序是未定义的。 如果reduceOptions 为OrderedReduce,则reduceFunction 将按照原始序列的顺序调用。
void sum(int& result ,int i)
{
qDebug()<<"result = "<<result <<"i = "<<i<<"线程Id:"<<QThread::currentThreadId();
result += i;
}
bool divisibleBy3(const int & i)
{
qDebug()<<QThread::currentThreadId();
return i % 3 == 0;
}
int main(int argc, char *argv[])
{
QList<int> list;
for (int i = 1;i < 12;++i)
{
list << i;
}
QFuture<int> result = QtConcurrent::filteredReduced(list,divisibleBy3,sum,QtConcurrent::SequentialReduce);
QThread::msleep(1000);
qDebug()<<list;
qDebug()<<"列表中能被3整除的数加起来:"<<result;
}
16、template <typename ResultType, typename Iterator, typename KeepFunctor, typename ReduceFunctor> QFuture<ResultType> filteredReduced(Iterator begin, Iterator end, KeepFunctor filterFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions = ReduceOptions(UnorderedReduce | SequentialReduce))
重载函数。
QFuture<int> result = QtConcurrent::filteredReduced(list.begin(),list.end(),divisibleBy3,sum,QtConcurrent::SequentialReduce);
17、template <typename Sequence, typename MapFunctor> QFuture<void> map(Sequence &sequence, MapFunctor function)
按顺序为每个项目调用一次 function。该函数传递了对项目的引用,因此对项目所做的任何修改都将按顺序显示。
QList<int> list;
for (int i = 1;i < 12;++i)
{
list << i;
}
QtConcurrent::map(list,[](int & i)
{
++i;
});
QThread::msleep(1000);
qDebug()<<list;
18、template <typename Iterator, typename MapFunctor> QFuture<void> map(Iterator begin, Iterator end, MapFunctor function)
重载函数。
19、template <typename Sequence, typename MapFunctor> QFuture<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType> mapped(const Sequence &sequence, MapFunctor function)
按顺序为每个项目调用一次 function ,并作为结果返回到QFuture。可以使用 QFuture::const_iterator 或 QFutureIterator 来迭代结果。
function 的参数类型必须是常引用。
QString run1(const int & i)
{
return QString("we get %1").arg(i);
}
int main(int argc, char *argv[])
{
QList<int> list;
for (int i = 1;i < 12;++i)
{
list << i;
}
QFuture<QString> result = QtConcurrent::mapped(list,run1);
result.waitForFinished();
qDebug()<<result.results();
for (auto it = result.constBegin();it != result.constEnd();++it)
{
qDebug()<<*it;
}
QFutureIterator<QString> it(result);
while (it.hasNext())
{
qDebug()<<it.peekNext()<<it.next();
}
}
20、template <typename Iterator, typename MapFunctor> QFuture<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType> mapped(Iterator begin, Iterator end, MapFunctor function)
重载函数。
21、template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor> QFuture<ResultType> mappedReduced(const Sequence &sequence, MapFunctor mapFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions = ReduceOptions(UnorderedReduce | SequentialReduce))
按顺序为每个项目调用一次 mapFunction。 每个 mapFunction 的返回值传递给 reduceFunction。
请注意,虽然 mapFunction 是并发调用的,但一次只有一个线程会调用 reduceFunction。
调用reduceFunction 的顺序由reduceOptions 决定。
void sum(int& result ,int i)
{
qDebug()<<"result = "<<result <<"i = "<<i<<"线程Id:"<<QThread::currentThreadId();
result += i;
}
int plus(const int & i)
{
qDebug()<<"plus() 线程Id:"<<QThread::currentThreadId();
return i + 10;
}
int main(int argc, char *argv[])
{
QList<int> list;
for (int i = 1;i < 12;++i)
{
list << i;
}
QFuture<int> result = QtConcurrent::mappedReduced(list,plus,sum,QtConcurrent::SequentialReduce);
qDebug()<<result;
}
22、template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor> QFuture<ResultType> mappedReduced(Iterator begin, Iterator end, MapFunctor mapFunction, ReduceFunctor reduceFunction, QtConcurrent::ReduceOptions reduceOptions = ReduceOptions(UnorderedReduce | SequentialReduce))
重载函数。
23、template <typename T> QFuture<T> run(Function function, ...)
等同于:
QtConcurrent::run(QThreadPool::globalInstance(), function, ...);
在单独的线程中运行函数。该线程取自全局 QThreadPool。请注意,该函数可能不会立即运行,函数只会在线程可用时运行。
T 与函数的返回值类型相同。
void debug(const QString & str)
{
qDebug()<<"string = "<<str;
}
int main(int argc, char *argv[])
{
QFuture<void> result = QtConcurrent::run(debug,QString("xx"));
result.waitForFinished();
result = QtConcurrent::run(QThreadPool::globalInstance(),debug,QString("xx"));
result.waitForFinished();
result = QtConcurrent::run([](const QString & str)
{
qDebug()<<"string = "<<str;
},QString("xx"));
result.waitForFinished();
}
如果是重载函数不能直接运行。
void foo(int arg);
void foo(int arg1, int arg2);
...
QFuture<void> future = QtConcurrent::run(foo, 42);
以上代码会报错。运行重载函数有三种方法:
QFuture<void> future = QtConcurrent::run([] { foo(42); }); //1
QFuture<void> future = QtConcurrent::run(static_cast<void(*)(int)>(foo), 42); //2
QFuture<void> future = QtConcurrent::run(qOverload<int>(foo), 42); //3
24、template <typename T> QFuture<T> run(QThreadPool *pool, Function function, ...)
在单独的线程中运行函数。该线程取自 QThreadPool 池。 请注意,该函数可能不会立即运行,函数只会在线程可用时运行。
T 与函数的返回值类型相同。