Qt Concurrent

Qt并发编程

QtConcurrent命名空间提供了高级api,使编写多线程程序成为可能,而无需使用低级线程原语,如互斥锁、读写锁、等待条件或信号量。用QtConcurrent编写的程序会根据可用处理器内核的数量自动调整所使用的线程数。这意味着今天编写的应用程序在未来部署到多核系统时将继续可扩展。

QtConcurrent包括用于并行列表处理的函数式编程风格api,包括用于共享内存(非分布式)系统的MapReduce和FilterReduce实现,以及在GUI应用程序中管理异步计算的类:

map函数

map函数将函数应用到容器中的每个项,并就地修改项。
函数有两个参数,第一个参数是一个集合,第二个参数是一个函数,且需要为静态函数

#include <QList>
#include <QThread>
#include <QDebug>
#include <QGuiApplication>
#include <qtconcurrentmap.h>

#include <functional>

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    std::function<void(int)> calculate_function = [](int value) -> void
    {
        qDebug()  << QThread::currentThreadId() << value;
    };

    QList<int> array = { 1 ,3 ,5 ,7 };

    QFuture<void> f = QtConcurrent::map(array,calculate_function);
    f.waitForFinished();

    return 0;
}

mapped

mapped函数与map类似,只是会将函数返回值返回到一个新的容器中

#include <QList>
#include <QThread>
#include <QDebug>
#include <QGuiApplication>
#include <qtconcurrentmap.h>

#include <functional>

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    std::function<int(int)> calculate_function = [](int value) -> int
    {
        qDebug()  << QThread::currentThreadId() << value;
        return value + qrand();
    };

    QList<int> array = { 1 ,3 ,5 ,7 };

    QFuture<int> f = QtConcurrent::mapped(array,calculate_function);


    f.waitForFinished();

    qDebug()  << f.results();

    return 0;
}

mappedReduced

mappedReduced函数一共有三个参数,可参看QtConcurrent Word Count Example的例子进行学习。

#include <QList>
#include <QThread>
#include <QDebug>
#include <QGuiApplication>
#include <qtconcurrentmap.h>

#include <functional>


int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    std::function<int(int)> calculate_function = [](int value) -> int
    {
        qDebug()  << QThread::currentThreadId() << value;
        return value;
    };

    //第二个参数需要限定为const ,每次执行完calculate_function后会将前一个次执行的结果和后一次执行的结果相加
    std::function<void(int&,const int&)> calculate_function2 = [](int& value,const int& result) -> void
    {
        value += result;
    };


    QList<int> array = { 1 ,3 ,5 ,7 };

    QFuture<int> f = QtConcurrent::mappedReduced<int>(array,calculate_function,calculate_function2);


    f.waitForFinished();

    qDebug()  << f.results();

    return 0;
}

简单的示例

class widget : public QWidget
{
public:
    widget(){
        layout = new QGridLayout;
        QHBoxLayout *h = new QHBoxLayout(this);
        QPushButton *btn = new QPushButton("open");

        h->addLayout(layout,9);
        h->addWidget(btn);
        connect(btn,&QPushButton::clicked,this,&widget::open);
    }

    ~widget(){}

public slots:
    void open() {
    	//获取图像路径,作为map第一个参数的容器
        QStringList files =QFileDialog::getOpenFileNames(this,"Select one or more files to open","./","Images (*.png *.xpm *.jpg)");
        if(files.isEmpty()) return;
        QLayoutItem *child;
        while ((child = layout->takeAt(0)) != 0)
        {
            layout->removeWidget(child->widget());
            child->widget()->setParent(0);
            delete child;
        }
        qDeleteAll(labels);
        labels.clear();

        for (int i =0;i < files.count(); i++) {
            QLabel *imageLabel = new QLabel;
            imageLabel->setFixedSize(50,50);
            layout->addWidget(imageLabel,i % 6, i /6);
            labels.append(imageLabel);
        }
		//map函数第二个参数,通过线程进行异步加载
        std::function<QImage(const QString&)> scale = [](const QString &imageFileName) {
            QImage image(imageFileName);
            qDebug() << QThread::currentThreadId();
            return image.scaled(QSize(50, 50), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
        };

        static QFutureWatcher<QImage> futureWatcher;
        futureWatcher.setFuture(QtConcurrent::mapped(files, scale));
        connect(&futureWatcher, &QFutureWatcher<QImage>::resultReadyAt, [=](int num){
            labels[num]->setPixmap(QPixmap::fromImage(futureWatcher.resultAt(num)));
        });
        connect(&futureWatcher, &QFutureWatcher<QImage>::finished, [=](){
            qDebug()  << "finish";
        });
        futureWatcher.waitForFinished();
    }
private:
    QList<QLabel*> labels;
    QGridLayout *layout;
};


int main(int argc, char **argv)
{
    QApplication app(argc, argv);

    widget w;
    w.show();

    app.exec();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值