专业seo整站优化,ftp上传安装wordpress,做漫画网站,学完html怎么做网站文章目录一、QtConcurrent 简介二、常用功能分类2.1 异步运行一个函数#xff08;无返回值#xff09;2.2 异步运行一个带参数的函数#xff08;有返回值#xff09;2.3 绑定类成员函数2.4 容器并行处理#xff08;map#xff09;三、线程池控制四、取消任务五、典型应用…
文章目录一、QtConcurrent 简介二、常用功能分类2.1 异步运行一个函数无返回值2.2 异步运行一个带参数的函数有返回值2.3 绑定类成员函数2.4 容器并行处理map三、线程池控制四、取消任务五、典型应用场景六、完整示例并发下载图片一、QtConcurrent 简介
QtConcurrent 是 Qt 提供的一个高级并发编程模块属于 QtConcurrent 命名空间旨在简化多线程任务的执行。它支持并行执行算法如 map、filter、reduce还支持异步任务运行和结果管理不需要显式管理 QThread。
模块介绍 头文件包含
#include QtConcurrent模块依赖
QT concurrent常用功能
二、常用功能分类
2.1 异步运行一个函数无返回值
QtConcurrent::run([]() {qDebug() 后台线程中执行任务 QThread::currentThread();
});2.2 异步运行一个带参数的函数有返回值
int add(int a, int b) {return a b;
}QFutureint future QtConcurrent::run(add, 3, 5);// 后续获取结果
int result future.result(); // 阻塞直到完成
qDebug() 结果是 result;2.3 绑定类成员函数
class Worker {
public:int multiply(int x, int y) {return x * y;}
};Worker worker;
QFutureint future QtConcurrent::run(worker, Worker::multiply, 4, 6);2.4 容器并行处理map
并发修改容器元素原地修改
QListint numbers {1, 2, 3, 4, 5};auto doubleIt [](int n) {n * 2;
};QtConcurrent::map(numbers, doubleIt);// 输出: 2 4 6 8 10并发映射容器到新容器mapped
QListint numbers {1, 2, 3};auto square [](int n) {return n * n;
};QListint squares QtConcurrent::mapped(numbers, square).results();
// 输出: 1 4 9并发过滤filtered
QStringList names {Alice, Bob, Eve};auto isShort [](const QString name) {return name.length() 3;
};QStringList shortNames QtConcurrent::filtered(names, isShort).results();
// 输出: Bob, Eve2.5 使用 QFutureWatcher 监听结果推荐与 UI 配合
QFutureWatcherQString *watcher new QFutureWatcherQString(this);connect(watcher, QFutureWatcherQString::finished, this, []() {QString result watcher-result();qDebug() 计算完成结果为: result;
});QFutureQString future QtConcurrent::run([]() {QThread::sleep(2);return QString(Hello from thread);
});watcher-setFuture(future);三、线程池控制
QtConcurrent 默认使用全局 QThreadPool可通过如下方式调整
QThreadPool::globalInstance()-setMaxThreadCount(8);或者使用局部线程池
QThreadPool pool;
QtConcurrent::run(pool, someFunction);四、取消任务
可通过 QFuture 中的 cancel() 方法取消任务
QFuturevoid future QtConcurrent::run([]{for (int i 0; i 100; i) {if (QThread::currentThread()-isInterruptionRequested()) {return;}QThread::msleep(100);}
});// 取消任务
future.cancel();
五、典型应用场景 六、完整示例并发下载图片
效果目标 核心类ImageDownloader
// ImageDownloader.h#ifndef IMAGEDOWNLOADER_H
#define IMAGEDOWNLOADER_H#include QObject
#include QNetworkAccessManager
#include QNetworkReply
#include QSemaphoreclass ImageDownloader : public QObject
{Q_OBJECT
public:explicit ImageDownloader(QObject *parent nullptr);void setMaxConcurrent(int count); // 设置最大并发数void downloadImages(const QStringList urls, const QString saveDir);signals:void imageDownloaded(const QString url, const QString filePath);void downloadFailed(const QString url, const QString error);void allFinished();private:void downloadOne(const QString url, const QString saveDir, int retryCount 3);QSemaphore m_semaphore; // 控制并发数int m_maxConcurrent 5;
};#endif // IMAGEDOWNLOADER_H// ImageDownloader.cpp#include ImageDownloader.h
#include QDir
#include QFile
#include QFileInfo
#include QNetworkRequest
#include QThread
#include QDebug
#include QtConcurrentImageDownloader::ImageDownloader(QObject *parent): QObject(parent), m_semaphore(m_maxConcurrent)
{}void ImageDownloader::setMaxConcurrent(int count)
{m_maxConcurrent count;m_semaphore QSemaphore(m_maxConcurrent);
}void ImageDownloader::downloadImages(const QStringList urls, const QString saveDir)
{for (const QString url : urls) {QtConcurrent::run([]() {m_semaphore.acquire(); // 限制并发downloadOne(url, saveDir);m_semaphore.release();});}// 可选全部下载完再发信号略
}void ImageDownloader::downloadOne(const QString urlStr, const QString saveDir, int retryCount)
{QNetworkAccessManager manager;QNetworkRequest request(QUrl(urlStr));QNetworkReply *reply manager.get(request);QEventLoop loop;QObject::connect(reply, QNetworkReply::finished, loop, QEventLoop::quit);loop.exec();if (reply-error() QNetworkReply::NoError) {QByteArray data reply-readAll();QUrl url(urlStr);QString fileName QFileInfo(url.path()).fileName();QString fullPath QDir(saveDir).filePath(fileName);QFile file(fullPath);if (file.open(QIODevice::WriteOnly)) {file.write(data);file.close();emit imageDownloaded(urlStr, fullPath);} else {emit downloadFailed(urlStr, 文件保存失败);}} else {if (retryCount 0) {qDebug() 下载失败重试: urlStr;downloadOne(urlStr, saveDir, retryCount - 1);} else {emit downloadFailed(urlStr, reply-errorString());}}reply-deleteLater();
}使用示例
ImageDownloader *downloader new ImageDownloader(this);
downloader-setMaxConcurrent(5); // 最多5张图同时下载QStringList urls {https://example.com/a.jpg,https://example.com/b.jpg,https://example.com/c.jpg
};QString savePath QDir::currentPath() /images;connect(downloader, ImageDownloader::imageDownloaded, this, [](const QString url, const QString path){qDebug() 下载成功: url - path;
});connect(downloader, ImageDownloader::downloadFailed, this, [](const QString url, const QString error){qWarning() 下载失败: url error;
});downloader-downloadImages(urls, savePath);