QtConcurrent::run 如何停止后台任务

Posted

技术标签:

【中文标题】QtConcurrent::run 如何停止后台任务【英文标题】:QtConcurrent::run how to stop background task 【发布时间】:2016-06-13 19:51:15 【问题描述】:

我也有这样的情况:stop thread started by qtconcurrent::run

我需要在 QMainWindow 的 closeEvent 上关闭子线程(从 QtConcurrent::run 开始)。 但是我在子线程中的函数使用来自 *.dll 的代码:我不能使用循环,因为我所做的只是调用 external dll 之类的

QFuture<void> = QtConcurrent::run(obj->useDllfunc_with_longTermJob());

当我使用 x 按钮关闭应用程序时,我的 gui 已关闭,但带有 _longTermJob() 的第二个线程仍然有效,完成时出现错误。 我知道一些决定:

    使用其他函数,如 map() 或其他 QFuture.cancel/stop 功能,而不是 QtConcurrent::run()。但我只需要一个函数调用。 run() 是我需要的。 或使用 QThread 代替 Concurrent。但这对我不利。

什么方法更简单更好,我该如何实现?有没有我没有列出的方法? 您能否提供小代码示例以供决策。谢谢!

【问题讨论】:

***.com/questions/32952474/… 【参考方案1】:

QtConcurrent::run 在这里不是问题。您必须有办法停止dllFuncWithLongTermJob。如果你没有这样的方法,那么你使用的 API 就坏了,你就不走运了。没有什么可以做的通常是安全的。强制终止线程可能会使堆处于不一致状态等 - 如果您需要终止线程,则需要立即中止应用程序。

希望您可以调用类似stopLongTermJob 的方法来设置一些中断dllFuncWithLongTermJob 的标志。

然后:

auto obj = new Worker;
auto objFuture = QtConcurrent::run([=]obj->dllFuncWithLongTermJob(););

打断:

obj->stopLongTermJob(); // must be thread-safe, sets a flag
objFuture.waitForFinished();

【讨论】:

实际上OP可能会做一些事情,但这完全取决于DLL的作用。如果 dllFuncWithLongTermJob 只是一种无状态的一次性运行后忘记它的函数,那么它可以在子进程中运行,它可以被杀死而不会对主程序造成严重后果。那只是使用操作系统进行清理工作。不用说,这是最后的解决方案,我只会在没有适当的可中断替代方案的情况下使用它。 @odelande 在单独的进程中运行它还有很多好处。当然,操作系统清理是其中的一部分。另一个重要的部分是 dll 在突然终止时不会破坏 your 状态。事实上,在子进程中运行它是一个绝妙的主意! 如果我理解正确 - 我需要使用 QThread 而不是 QtConcurrent 来控制子线程?并发在这种情况下没有用吗?那时我只是在 MainWindow 中实现 closeEvent 等待对话框,如果子线程计数!= 0x00。

以上是关于QtConcurrent::run 如何停止后台任务的主要内容,如果未能解决你的问题,请参考以下文章

如何将 QtConcurrent::run 函数(或类似函数)中的 progressText 传递给 QFutureWatcher?

如何将字符串数组传递给 QtConcurrent::run?

QtConcurrent::run 如何在主线程上结束?

使用 QtConcurrent::run() 修改成员变量?

QtConcurrent::run 发出信号

QtConcurrent::run 异常通知