批量执行任务:使用QtConcurrent实现
目录
批量执行一系列任务是软件中常见的需求,通常采用并行执行多个任务的方式加快速度。 比如使用下载软件下载多个文件时,下载软件会根据用户设置,同时下载队列中的几个文件,每当一个下载任务结束时,会自动启动下一个下载任务。
本文介绍如何使用 QtConcurent 实现批量执行任务的功能。下面的场景来自下载小说的软件。
方案
使用 QtConcurrent::map
执行批量任务。
QtConcurrent::map
使用全局线程池(来自QThreadPool::globalInstance
)来执行程序,同时执行程序的个数由全局线程池设置的线程数决定。
同时,QtCocurrent::map
使用 QFuture
返回异步计算结果,我们可以使用 QFutureWatcher
与 QFuture
的连接实现与任务的交互。
实现
首先设置全局线程池的线程个数,例如设置4个线程。
QThreadPool::globalInstance()->setMaxThreadCount(4);
创建对任务进行监控的 QFutureWatcher
。
QFutureWatcher<void> future_watcher;
准备需要批量执行的任务,比如下面下载小说章节的任务 DownloadTask
。
QVector<downloadTask> download_tasks_;
for(int i=0; i<novel_content_model_->rowCount(); i++)
{
DownloadTask task;
task.name_ = novel_content_model_->item(i, 0)->text();
task.link_ = novel_content_model_->item(i, 1)->text();
task.directory_ = local_directory;
task.task_no_ = i;
download_tasks_.push_back(task);
}
开始执行批量任务:
future_watcher_.setFuture(QtConcurrent::map(download_tasks_, [this](const DownloadTask &task){
// 执行任务,省略代码
}));
QtConcurrent::map
会使用全局线程池自动执行所有任务。
QFutureWatcher
可以暂停或恢复任务的执行。
future_watcher_.setPaused(checked);
未来计划
上面介绍使用 QtConcurrent 可以实现简单的批量执行任务功能。 但因为 QtConcurrent 只能使用全局线程池,缺乏更精细的控制手段,所以后续计划使用自定义的 QThreadPool 实现批量下载功能。