QT高级线程API总结(二)QtConcrrent::map

目录

 

1、Header: #include

2、qmake: QT += concurrent

3、 详情描述

4 number functions

4.1 QtConcurrent::mapped

4.2 QtConcurrent::map

4.3 QtConcurrent::mappedReduced

4.4 QtConcurrent::blockingMap

4.5 QtConcurrent::blockingMapped

4.6 QtConcurrent:: blockingMappedReduced

5、API附加特征

5.1 使用迭代器代替容器

5.2 阻塞变量

5.3 使用成员函数

5.4 使用函数对象

5.5 多个函数参数

6、代码示例

6.1  QtConcurrent::mapped()

6.2  QtConcurrent::map()

6.3 QtConcurrent::mappedReduced()


1、Header: #include <QtConcrrent>

2、qmake: QT += concurrent

3、 详情描述

QtConcurrent::map(), QtConcurrent::mapped() 和 QtConcurrent::mappedReduced() 函数在一个序列中(例如:QList 或者 QVector )并行的运行计算。

QtConcurrent::map() 在原地修改序列;

QtConcurrent::mapped() 返回一个包含修改内容的新序列;

QtConcurrent::mappedReduced() 返回单个结果;

这些函数都是Qt并发框架的一部分。

上面的每一个函数都有一个阻塞变量,它返回最终结果,而不是QFuture。也可以异步调用。

QList<QImage> images = ...;

// Each call blocks until the entire operation is finished.

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

QtConcurrent::blockingMap(images, scale);

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

注意上面的返回结果不是QFuture类型,而是真实的结果类型(在本例中,QList<QImage>和QImage).

4 number functions

4.1 QtConcurrent::mapped

QtConcurrent::mapped() 接受一个输入序列和映射函数。然后对序列中的每个项调用这个映射函数,并返回一个包含映射函数返回值的新序列。

必须是如下格式:

U function(const T &t);

U和T可以是任意类型(可以相同),但是T必须与存储在序列中的类型匹配。函数返回修改或者映射的内容。如下所示:

QImage scaled(const QImage &image)

{

         return image.scaled(100, 100);

}

QList<QImage> images = ...;

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

返回结果可以通过QFuture获得。有关如何在应用中使用更多的QFuture信息,可以参考QFuture和QFutureWatcher文档。

如果想要修改一个序列,可使用QtConcrrent::map()。

4.2 QtConcurrent::map

使用 QtConcurrent::map() 可以修改一个序列,map()函数必须是以下形式:

U function(T &t);

注意:这里不会使用函数的返回值和返回类型。

使用map()类似于使用mapped():

void scale(QImage &image)

{

   image = image.scaled(100, 100);

}

QList<QImage> images = ...;

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

由于容器内容已被修改,QtConcrrent::map()不会通过QFuture返回任何结果。但是,仍然可以使用QFuture和QFutureWatcher来监视映射状态。

4.3 QtConcurrent::mappedReduced

QtConcurrent::mappedReduced() 类似于 QtConcurrent::mapped(),但不是返回一个带有新结果的序列,而是使用reduce函数讲结果组合成一个单独的值。

函数模版:

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

T是最终的结果类型,U是映射函数的返回类型。注意,reduce函数的返回值和返回类型没有被使用。

如下方式调用:
 

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);

将对map函数函数返回的每个结果都调用一次reduce函数,并且会将中间值合并到结果变量中。QtConcrrent::mappedReduced()保证每次只有一个线程会调用reduce,所以不需要使用互斥锁来锁定结果变量。QtConcurrent::ReduceOptions枚举类型提供一个控制顺序的方法。QtConcurrent::UnorderedReduce是默认的, 其顺序未定义, 而 QtConcurrent::OrderedReduce 确保按原始序列输出。

4.4 QtConcurrent::blockingMap

void QtConcurrent::blockingMap(Sequence &sequence, MapFunction function)

对每个项按顺序调用函数一次。该函数将向项传递一个引用,以便对项所做的任何修改都将依次显示。

注意:这个函数将阻塞直到序列中的所有项都被处理完。

void QtConcurrent::blockingMap(Iterator begin, Iterator end, MapFunction function)

从头到尾对每个项调用函数一次。该函数将向该元素传递一个引用,以便对该元素所做的任何修改都将出现在迭代器所属的序列中。

注意:这个函数将会阻塞,直到迭代器到达正在处理的序列的末尾。

4.5 QtConcurrent::blockingMapped

T QtConcurrent::blockingMapped(const Sequence &sequence, MapFunction function)

对序列中的每个项调用函数一次,并返回包含结果的序列。结果的类型将匹配我的MapFunction返回的类型。

注意:这个函数将阻塞直到序列中的所有项都被处理完。

T QtConcurrent::blockingMapped(ConstIterator begin, ConstIterator end, MapFunction function)

对每个条目从头到尾调用函数一次,并返回一个带有结果的容器。将容器类型指定为a模板参数,如下所示:

QList<int> int = QtConcurrent::blockingMapped<QList<int> >(beginIterator, endIterator, fn);

注意:这个函数将会阻塞,直到迭代器到达正在处理的序列的末尾。

4.6 QtConcurrent:: blockingMappedReduced

T QtConcurrent::blockingMappedReduced(const Sequence &sequence, MapFunction mapFunction, ReduceFunction reduceFunction, QtConcurrent::ReduceOptions reduceOptions = UnorderedReduce | SequentialReduce)

对每个项按顺序调用mapFunction一次。每个mapFunction的返回值被传递给reduceFunction。

注意,当mapFunction被并发调用时,每次只有一个线程会调用reduceFunction。reduceFunction的调用顺序由reduceOptions决定。

注意:这个函数将阻塞直到序列中的所有项都被处理完。

T QtConcurrent::blockingMappedReduced(ConstIterator begin, ConstIterator end, MapFunction mapFunction, ReduceFunction reduceFunction, QtConcurrent::ReduceOptions reduceOptions = UnorderedReduce | SequentialReduce)

对每个条目从头到尾调用mapFunction一次。每个mapFunction的返回值被传递给reduceFunction。

注意,当mapFunction被并发调用时,每次只有一个线程会调用reduceFunction。reduceFunction的调用顺序没有定义。

注意:这个函数将会阻塞,直到迭代器到达正在处理的序列的末尾。

5、API附加特征

5.1 使用迭代器代替容器

QList<QImage> images = ...;

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

// Map in-place only works on non-const iterators.

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

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

5.2 阻塞变量

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)。

5.3 使用成员函数

QtConcurrent::map()、QtConcurrent::mapped() 和 QtConcurrent::mappedReduced() 接受成员函数的指针,成员函数类类型必须与存储在序列中的类型匹配:

// Squeeze all strings in a QStringList.

QStringList strings = ...;

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

// 交换 images 列表中图片所有像素的 rgb 值

QList<QImage> images = ...;

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

// Create a set of the lengths of all strings in a list.

QStringList strings = ...;

QFuture<QSet<int> > wordLengths = QtConcurrent::mappedReduced(strings, &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);

5.4 使用函数对象

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))

5.5 多个函数参数

如果你想要使用带多个参数的map函数,你可以使用Lamada函数或者std::bind()将其转化为带一个参数的函数。

例如:我们将使用

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

scaledToWidth有三个参数(包含this指针),不能直接与QtConcrrent::mapped()一起使用,因为QtConcrrent::mapped()期望一个只有一个参数的函数。如要在QtConcrrent::mapped()中使用QImage::scaledToWidth(),我们必须为宽度和转换模式提供一个值:

QList<QImage> images = ...;

std::function<QImage(const QImage &)> scale = [](const QImage &img) {

           return img.scaledToWidth(100, Qt::SmoothTransformation);

};

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

6、代码示例

6.1  QtConcurrent::mapped()

    extern int func(const int &arg){
        return arg+1;
    };

    QList<int> list;
    list << 1 << 2 << 3 << 4 << 5 << 6;
    QFuture<int> future = QtConcurrent::mapped(list, func);
    qDebug() << "list: " << list << ", future:" << future.results();
    //输出: list:  (1, 2, 3, 4, 5, 6) , future: (2, 3, 4, 5, 6, 7)

6.2  QtConcurrent::map()

    QList<int> list;
    list << 1 << 2 << 3 << 4 << 5;
    qDebug() << "start list: " << list ;
    QFuture<void> future = QtConcurrent::map(list, func);
    QFutureWatcher<void> *watcher = new QFutureWatcher<void>(this);
    watcher->setFuture(future);
    connect(watcher, &QFutureWatcher<void>::finished, [=](){
        qDebug() << "finished list: " << list ;
    });
    //输出:
    //start list:  (1, 2, 3, 4, 5)
    //finished list:  (2, 3, 4, 5, 6)

6.3 QtConcurrent::mappedReduced()

    extern int func(const int &arg){
        return arg + 1;
    };
    
    void addCollage(int &result, const int &arg)
    {
        if(result < arg)
            result = arg;
    }
    
    QList<int> list;
    list << 1 << 2 << 3 << 4 << 5;
    QFuture<int> collage = QtConcurrent::mappedReduced(list, func, addCollage);

    collage.waitForFinished();
    qDebug() << collage.result();  //6

 

第1章 混合桌面/internet应用程序 1.1 internet相关窗口部件 1.2 webkit的使用 第2章 声音和视频 2.1 qsound和qmovie的使用 2.2 phonon多媒体框架 第3章 模型/视图表格模型 3.1 qt的模型/视图架构 3.2 用于表格的qstandarditemmodel 3.3 创建自定义表格模型 第4章 模型/视图树模型 4.1 用于树qstandarditemmodel的用法 4.2 创建自定义树模型 第5章 模型/视图委托 5.1 与数据类型相关的编辑器 5.2 与数据类型相关的委托 5.3 与模型相关的委托 第6章 模型/视图中的视图 6.1 qabstractitemview子类 .6.2 与模型相关的可视化视图 第7章 用qtconcurrent实现线程处理 7.1 在线程中执行函数 7.2 线程中的过滤和映射 第8章 用qthread实现线程处理 8.1 独立项的处理 8.2 共享项的处理 第9章 创建富文本编辑器 9.1 qtextdocument简介 9.2 创建自定义的文本编辑器 9.3 一个单行的富文本编辑器 9.4 编辑多行的富文本 第10章 创建富文本文档 10.1 高质量地输出qtextdocument文件 10.2 创建qtextdocument 10.3 输出和打印文档 10.4 绘制页面 第11章 创建图形/视图窗口 11.1 图形/视图架构 11.2 图形/视图窗口部件和布局 11.3 图形项简介 第12章 创建图形/视图场景 12.1 场景、项和动作 12.2 增强qgraphicsview的功能 12.3 创建可停靠的工具箱窗口部件 12.4 创建自定义图形项 第13章 动画和状态机框架 13.1 动画框架简介 13.2 状态机框架简介 13.3 动画和状态机的结合 结束语 精选书目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值