6

Is it possible to stop a Thread by its associated QFuture Object ? Currently i've been starting a video capturing process like this.

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

Inside the startLiveCapturing-Method an infinite loop is running that captures images and displays them. So if the user wants to stop that process he should simply press a button and that operation stops. But it seems that i can not stop this thread by calling the cancel method like this ?

this->cameraThreadRepresentation.cancel();

What i am doing wrong and how can i stop that thread or operation.

Sebastian Boldt
  • 5,283
  • 9
  • 52
  • 64

3 Answers3

8

From the documentation of QtConcurrent::run:

Note that the QFuture returned by QtConcurrent::run() does not support canceling, pausing, or progress reporting. The QFuture returned can only be used to query for the running/finished status and the return value of the function.

What you could do is have a button press set a boolean flag in your main window and build your infinite loop like this:

_aborted = false;

forever    // Qt syntax for "while( 1 )"
{
    if( _aborted ) return;

    // do your actual work here
}
Tim Meyer
  • 12,210
  • 8
  • 64
  • 97
  • This is the simplest 'one off' solution. See the answers to [QFuture that can be cancelled and report progress](http://stackoverflow.com/q/5423058/3610458) for other suggestions. – SensorSmith Mar 25 '16 at 16:22
  • Actually, this is a pretty awful solution failing to account for... well, *anything*. There be mutual exclusion dragons here. Instead, everyone almost certainly just wants to copy-and-pasta [Hatter](https://stackoverflow.com/users/471602/hatter)'s [masterful `ControllableTask` API](https://stackoverflow.com/a/16729619/2809027). It's only forty lines of code or so. It also actually works as expected, permitting arbitrary multithreaded tasks to be paused, resumed, stopped, and restarted. – Cecil Curry Apr 10 '18 at 06:03
  • I would recommend making that boolean an atomic. Otherwise an optimizer may remove the check for the bool and lead to different behavior on different compilers: https://en.cppreference.com/w/cpp/atomic/atomic – Atif May 10 '19 at 17:21
2

Why don't you create a boolean flag that you can test inside your capturing loop and when it is set, it jumps out and the thread exits?

Something like:

MainWindow::onCancelClick() // a slot
{
    QMutexLocker locker(&cancelMutex);
    stopCapturing = true;
}

And then for your threaded function:

MainWindow::startLiveCapturing()
{
   forever
   {

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

}
RobbieE
  • 4,280
  • 3
  • 22
  • 36
0

as Qt Document said, you can not use cancel() function fir QConcurrent::run() but you can cancel tasks by this answer :

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

MMT
  • 11
  • 2
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/late-answers/29872634) – isopach Sep 20 '21 at 20:34