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

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

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

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

this->cameraThreadRepresentation.cancel();

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

【问题讨论】:

    标签: multithreading qt qtconcurrent


    【解决方案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 的答案。
    • 实际上,这是一个非常糟糕的解决方案,无法解释......好吧,任何事情。这里有互斥龙。相反,几乎可以肯定,每个人都只想复制和粘贴Hattermasterful 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://stackoverflow.com/a/16729619/14906306

      【讨论】:

      • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多