StupidBeauty
Read times:838Posted at:Fri Oct 12 05:25:59 2012
- no title specified

Qt4.8文档翻译:<QtConcurrentMap> - 并行映射和映射-归并,<QtConcurrentMap> - Concurrent Map and Map-Reduce

这些函数是 Qt Concurrent 框架的一部分。

QtConcurrent::map ()、 QtConcurrent::mapped ()和 QtConcurrent::mappedReduced ()函数在一个序列(例如 QList QVector )中的各个条目上并行地进行运算。 QtConcurrent::map ()会原地修改该序列, QtConcurrent::mapped ()会返回一个包含修改后的数据的新序列,而 QtConcurrent::mappedReduced ()会返回一个单个的结果。

以上的每个函数都有一个阻塞模式的变种,会返回最终结果而不是一个 QFuture 。妳可以像使用那些异步模式的变种一样地使用它们。

QList < QImage > images = ...;

//以下每个调用都会阻塞,直到整个操作结束

QList < QImage > future = QtConcurrent ::blockingMapped(images, scaled);

QtConcurrent ::blockingMap(images, scale);

QImage collage = QtConcurrent ::blockingMappedReduced(images, scaled, addToCollage);

注意,以上示例中的结果的类型不是 QFuture 对象,而是真正的结果类型(在以上例子中,分别是 QList < QImage >和 QImage )。

并行映射,Concurrent Map

QtConcurrent::mapped ()需要传入一个输入序列和一个映射函数。这个映射函数会被针对序列中的每个条目调用一次,然后会返回一个新的序列,其中包含的是那些由映射函数返回的值。

映射函数必须是这样的形式:

U function(const T &t);

T和U可以是任意类型(它们甚至可以是同一类型),但是T必须符合序列中储存的条目的类型。这个函数返回的是修改过的、或者说是映射过的内容。

以下示例演示的是如何对一个序列中的所有条目应用缩放函数:

QImage scaled(const QImage &image)

{

return image.scaled(100, 100);

}

QList < QImage > images = ...;

QFuture < QImage > thumbnails = QtConcurrent ::mapped(images, scaled);

映射的结果是储存在 QFuture 中的。参考 QFuture QFutureWatcher 的文档,以了解如何在妳的程序中使用 QFuture

如果妳想原地修改一个序列,那么就使用 QtConcurrent::map ()。映射函数必须是这样的形式:

U function(T &t);

注意,映射函数的返回值和返回类型是无用的。

使用 QtConcurrent::map ()跟使用 QtConcurrent::mapped ()是类似的:

void scale( QImage &image)

{

image = image.scaled(100, 100);

}

QList < QImage > images = ...;

QFuture < void > future = QtConcurrent ::map(images, scale);

由于这个序列是原地修改的,所以 QtConcurrent::map ()不通过 QFuture 返回任何值。然而,妳仍然可以使用 QFuture QFutureWatcher 来跟踪这个映射过程的状态。

并行映射-归并,Concurrent Map-Reduce

QtConcurrent::mappedReduced ()与 QtConcurrent::mapped ()是类似的,但它不是返回一个包含新的结果的序列,而是使用一个归并函数来将这些结果组合到一个单独的返回值中。

归并函数必须是以下的形式:

V function(T &result, const U &intermediate)

T是最终结果的类型,U是映射函数的返回类型。注意,归并函数的返回值和返回类型是无用的。

像这样调用 QtConcurrent::mappedReduced ():

void addToCollage( QImage &collage, const QImage &thumbnail)

{

QPainter p(&collage);

static QPoint offset = QPoint (0, 0);

p.drawImage(offset, thumbnail);

offset += ...;

}

QList < QImage > images = ...;

QFuture < QImage > collage = QtConcurrent ::mappedReduced(images, scaled, addToCollage);

对于映射函数返回的每个结果,都会调用一次归并函数,而归并函数应当将 intermediate 合并到 result 变量中去。 QtConcurrent::mappedReduced ()确保了每一时刻都只会有一个线程调用归并函数,所以无需使用一个互斥锁来锁住结果变量。 QtConcurrent::ReduceOptions 枚举还使得妳可以控制归并的顺序。如果指定的是 QtConcurrent::UnorderedReduce (默认值),那么归并就是无序的,而指定 QtConcurrent::OrderedReduce 的话就可以确保归并是按照原来的序列中的顺序进行的。

附加的编程接口特性

使用迭代器来代替序列

以上每个函数都有一个以迭代器范围代替序列参数的变种。它们用起来与使用序列参数的变种是一样的:

QList < QImage > images = ...;

QFuture < QImage > thumbnails = QtConcurrent ::mapped(images.constBegin(), images.constEnd(), scaled);

//原地映射只支持非常量的迭代器

QFuture < void > future = QtConcurrent ::map(images.begin(), images.end(), scale);

QFuture < QImage > collage = QtConcurrent ::mappedReduced(images.constBegin(), images.constEnd(), scaled, addToCollage);

阻塞模式的变种

以上每个函数都有一个阻塞模式的变种,它们返回最终结果,而不是一个 QFuture 对象。用起来也与异步模式的变种是一样的:

QList < QImage > images = ...;

//以下每个调用都是阻塞的,直到整个操作完成

QList < QImage > future = QtConcurrent ::blockingMapped(images, scaled);

QtConcurrent ::blockingMap(images, scale);

QImage collage = QtConcurrent ::blockingMappedReduced(images, scaled, addToCollage);

注意,以上示例中的结果的类型不是 QFuture 对象,而是真正的结果类型(在以上例子中,分别是 QList < QImage >和 QImage )。

使用成员函数

QtConcurrent::map ()、 QtConcurrent::mapped ()和 QtConcurrent::mappedReduced ()允许使用成员函数的指针。所用的成员函数的类类型必须符合序列中储存的条目的类型:

//对一个QStringList中的所有字符串执行紧缩操作

QStringList strings = ...;

QFuture < void > squeezedStrings = QtConcurrent ::map(strings, & QString ::squeeze);

//对一个图片列表中的每张图片,交换其所有像素的rgb 值

QList < QImage > images = ...;

QFuture < QImage > bgrImages = QtConcurrent ::mapped(images, & QImage ::rgbSwapped);

//创建一个集合,其中包含的是一个字符串列表中所有字符串的长度

QStringList strings = ...;

QFuture < QSet < int > > wordLengths = QtConcurrent ::mappedReduced(string, & QString ::length, & QSet < int >::insert);

注意,在使用 QtConcurrent::mappedReduced ()的时候,妳可以自由地组合使用普通函数和成员函数:

//可以在使用QtConcurrent::mappedReduced()的时候将普通函数和成员函数自由组合

//计算一个字符串列表中的字符串的平均长度

extern void computeAverage( int &average, int length);

QStringList strings = ...;

QFuture < int > averageWordLength = QtConcurrent ::mappedReduced(strings, & QString ::length, computeAverage);

//创建一个集合,其中包含的是一个图片列表中所有图片里出现过的颜色

extern int colorDistribution(const QImage &string);

QList < QImage > images = ...;

QFuture < QSet < int > > totalColorDistribution = QtConcurrent ::mappedReduced(images, colorDistribution, QSet < int >::insert);

使用函数对象

QtConcurrent::map ()、 QtConcurrent::mapped ()和 QtConcurrent::mappedReduced ()允许使用函数对象,利用这一点可以在函数调用中加入状态信息。必须使用result_type 这个类型别名(typedef)来定义该函数调用操作符的结果类型:

struct Scaled

{

Scaled( int size)

: m_size(size) { }

typedef QImage result_type;

QImage operator()(const QImage &image)

{

return image.scaled(m_size, m_size);

}

int m_size;

};

QList < QImage > images = ...;

QFuture < QImage > thumbnails = QtConcurrent ::mapped(images, Scaled(100));

使用绑定的函数参数

注意,Qt 不提供对绑定函数的支持。这个功能是由第三方库提供的,例如 Boost C++ TR1库扩展

如果妳想使用一个需要多于一个参数的映射函数,那么妳可以使用boost::bind()或std::tr1::bind()来将它转换成一个只需要一个参数的函数。

举个例子,我们要使用 QImage::scaledToWidth ():

QImage QImage ::scaledToWidth( int width, Qt ::TransformationMode) const;

scaledToWidth需要3个参数(包括“this”指针),无法直接用在 QtConcurrent::mapped ()中,因为 QtConcurrent::mapped ()需要一个只有一个参数的函数。要想在 QtConcurrent::mapped ()中使用 QImage::scaledToWidth ()的话,我们需要提供一个宽度( width )值和变换( transformation )模式:

boost::bind(& QImage ::scaledToWidth, 100, Qt ::SmoothTransformation)

boost::bind()的返回值是一个拥有以下特征(signature)的函数对象(函子(functor)):

QImage scaledToWith(const QImage &image)

这就满足了 QtConcurrent::mapped ()的要求,以下是完整的示例:

QList < QImage > images = ...;

QFuture < QImage > thumbnails = QtConcurrent ::mapped(images, boost::bind(& QImage ::scaledToWidth, 100 Qt ::SmoothTransformation));


Your opinions
Your name:Email:Website url:Opinion content:
- no title specified

HxLauncher: Launch Android applications by voice commands

 
Recent comments
2017年4月~2019年4月垃圾短信排行榜Posted at:Thu Sep 26 04:51:48 2024
Qt5.7文档翻译:QWebEngineCookieStore类,QWebEngineCookieStore ClassPosted at:Fri Aug 11 06:50:35 2023盲盒kill -9 18289 Grebe.20230517.211749.552.mp4