使用 QtConcurrent 在 QT 中进行多线程
Posted
技术标签:
【中文标题】使用 QtConcurrent 在 QT 中进行多线程【英文标题】:Multithreading in QT using QtConcurrent 【发布时间】:2013-11-14 08:49:37 【问题描述】:我正在用 Qt 开发一个应用程序,它有时会处理一堆视频。 它工作正常,但在进程阶段它只有 40-60% 的 cpu 使用率,所以我尝试使其成为多线程。
我使用 QtConcurrent 导致他的“高度”而不是更传统的线程管理,我的代码很简单:
for(int i = 0; i < totalVideos; i++)
QFuture<ResultClass *> futureToken = QtConcurrent::run(this, process, listOfVideos.takeFirst());
QFutureWatcher<ResultClass *>* fw = new QFutureWatcher<ResultClass *>();
connect(fw, SIGNAL(finished()), this, SLOT(manageResult));
fw->setFuture(futureToken);
aaa 并且它可以工作,100% 的 CPU 使用率和大约 25-30% 的速度。但它会产生大约 65 个新线程(不管它处理 25 或 250 个视频),并且这些线程中的大多数在处理阶段后都不会消失。
我的问题是:这种方法正确吗?是不是太生了?我应该“手动”控制线程创建吗? QtConcurrent 模块是否会处理所有问题,所以我不应该关心线程管理? 85个线程太多了吗?我应该在进程阶段之后尝试杀死其中的一些吗??
仅查看活动监视器即可完成所有观察。
提前致谢。
【问题讨论】:
另一种选择是使用 QThreadPool 并直接限制线程数(还有你的 futureWatcher 泄漏,除非你在 manageResult 槽中删除它) 是的,我在插槽中删除它们(使用 deleteLater()),感谢您指出这一点。 从技术上讲,当this
在未来完成之前被销毁时,它们仍然会泄漏(将此添加到构造函数以修复该问题)
【参考方案1】:
如果您阅读this thread,QtConcurrent 的未来似乎是不确定的。
拥有更多处理内核的线程有点多余。如果你有一个核心和 2 个线程在运行,处理器会花时间在 2 个线程之间切换处理,但会给用户一个同时处理的外观。
在内核和线程数相同的情况下,线程可以在内核之间拆分。
一旦你的内核多于线程,你就会回到原来的方法,即内核在需要处理的线程之间来回跳跃。
使用 QThread 实际上很容易做到,因为 QThread 不是直接的线程,而是线程控制器。您可以阅读有关如何'really truly use QThreads' here.
正如它所描述的,您创建继承到 QObject 的对象并将其移动到 QThread。很少提及的是,如果需要,您可以将多个对象移动到新的 QThread。
【讨论】:
我知道它是多余的,但我没有创建它们。我虽然 QtConcurrent 将任务移动到它在文档中说的适当线程:“在单独的线程中运行函数。线程取自全局 QThreadPool。请注意,该函数可能不会立即运行;该函数只会在以下情况下运行有一个线程可用。”我不知道所有线程产卵是从哪里来的。 可能是在进行视频处理的同时也在产生线程。我建议将您的代码转换为使用 QThread 并查看您从中获得的性能作为比较。 我会这样做,并会发布结果。 “拥有更多线程来处理 [原文如此] 处理内核有点多余”——仅当并行任务是仅计算时;如果任务有任何 I/O 操作,则可能需要更多线程以防止内核在可能正在处理时处于空闲状态。以上是关于使用 QtConcurrent 在 QT 中进行多线程的主要内容,如果未能解决你的问题,请参考以下文章
从qt中的另一个线程运行qtconcurrent时如何关闭程序
Qt基础之十六:QtConcurrent和QThreadPool