停止由 QtConcurrent::run 启动的线程?

Posted

技术标签:

【中文标题】停止由 QtConcurrent::run 启动的线程?【英文标题】:Stop Thread started by QtConcurrent::run? 【发布时间】:2013-09-17 09:03:59 【问题描述】:

是否可以通过关联的 QFuture 对象来停止线程? 目前我一直在开始这样的视频捕捉过程。

this->cameraThreadRepresentation = QtConcurrent::run(this,&MainWindow::startLiveCapturing);

在 startLiveCapturing-Method 内部,一个无限循环正在运行,用于捕获图像并显示它们。因此,如果用户想要停止该过程,他只需按下一个按钮,该操作就会停止。 但似乎我不能通过调用这样的取消方法来停止这个线程?

this->cameraThreadRepresentation.cancel();

我做错了什么以及如何停止该线程或操作。

【问题讨论】:

【参考方案1】:

来自QtConcurrent::run的文档:

请注意,QtConcurrent::run() 返回的 QFuture 不支持取消、暂停或进度报告。返回的QFuture只能用于查询函数的运行/结束状态和返回值。

你可以做的是在你的主窗口中按下按钮设置一个布尔标志,然后像这样构建你的无限循环:

_aborted = false;

forever    // Qt syntax for "while( 1 )"

    if( _aborted ) return;

    // do your actual work here

【讨论】:

这是最简单的“一次性”解决方案。有关其他建议,请参阅QFuture that can be cancelled and report progress 的答案。 实际上,这是一个非常糟糕的解决方案,无法解释......好吧,任何事情。这里有互斥龙。相反,几乎可以肯定,每个人都只想复制和粘贴Hatter 的masterful ControllableTask API。它只有四十行左右的代码。它实际上也按预期工作,允许暂停、恢复、停止和重新启动任意多线程任务。 我建议将该布尔值设为原子值。否则,优化器可能会删除对 bool 的检查并导致不同编译器上的不同行为:en.cppreference.com/w/cpp/atomic/atomic【参考方案2】:

你为什么不创建一个布尔标志,你可以在你的捕获循环中测试它,当它被设置时,它会跳出并且线程退出?

类似:

MainWindow::onCancelClick() // a slot

    QMutexLocker locker(&cancelMutex);
    stopCapturing = true;

然后是你的线程函数:

MainWindow::startLiveCapturing()

   forever
   

       ...
       QMutexLocker locker(&cancelMutex);
       if (stopCapturing) break;
   


【讨论】:

【参考方案3】:

正如Qt文档所说,你不能使用cancel()函数fir QConcurrent::run()但是你可以通过这个答案取消任务:

https://***.com/a/16729619/14906306

【讨论】:

虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review

以上是关于停止由 QtConcurrent::run 启动的线程?的主要内容,如果未能解决你的问题,请参考以下文章

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

QtConcurrent::run => QWaitCondition: 在线程仍在等待时被销毁

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

QtConcurrent::run 发出信号

QtConcurrent::run 异常通知

在 QtConcurrent::run 中使用 QSqlDatabase 连接(伪连接池)