Vinod
Vinod

Reputation: 1086

Stop QThread to execute

I am trying to implement timeout in my QT Application. I have used QThread to perform the operation (task on which timeout is required) and have used QElapsedTimer to count elapsed time waiting to perform the operation. Below is the code snippet

QElapsedTimer timeoutTimer;   // Timer to count the elapsed time waiting for the operation to complete.
long timeoutInterval=10000
MyThread mThread();   // QThread implementation
timeoutTimer.start(); 
mThread.start();   

while((timeoutTimer.elapsed() < timeoutInterval) &&  mThread.isRunning()){
    sleep(5);
}


if(mThread.isRunning()){
  mThread.terminate();
}

Now, if task is not completed and timeout happens I get "Destroyed while thread is still running" and application gets crashed. I tried to call terminate() function of QThread but it is working on Windows however on Linux I get segmentation fault.

Upvotes: 0

Views: 3595

Answers (2)

Pavel Strakhov
Pavel Strakhov

Reputation: 40502

You have mentioned that quit() doesn't work for your thread, so I suppose you have reimplemented QThread::run method and doesn't use event loop in your implementation. As the documentation says:

Subclassing QThread is unnecessary for most purposes, since QThread provides fully-functional thread management capabilities. Nonetheless, QThread can be subclassed if you wish to implement advanced thread management. This is done by adding new member functions to the subclass, and/or by reimplementing run(). QThread’s run() function is analogous to an application’s main() function — it is executed when the thread is started, and the thread will end when it returns.

Note: Prior to Qt 4.4, the only way to use QThread for parallel processing was to subclass it and implement the processing code inside run(). This approach is now considered bad practice; a QThread should only manage a thread, not process data.

So, do not subclass QThread. You can just use the standart event loop and signal-slot system to use your thread. You also can use more high-level interface such as QRunnable if it can be done for your task.

If you are sure that you want to reimplement QThread::run and eliminate advantages of event loop, than you should take care of stopping your thread manually. For example, you can use some boolean flag bool need_to_stop and check its value periodically as the thread runs. When you decided to stop the thread, set the flag's value to true and then call QThread::wait(). When QThread::run is finished because of the flag's value, your thread will be stopped and wait() will return. Note however that you can't simply use one flag simultaneously from both your new thread and GUI thread. You need some synchronization mechanism like QMutex. So, this thing is overcomplicated. Just don't subclass QThread if you don't want to do something really low-level.

Upvotes: 3

Ruslan F.
Ruslan F.

Reputation: 5776

Try using void QThread::quit () as mentioned in documentation

Tells the thread's event loop to exit with return code 0 (success). Equivalent to calling QThread::exit(0).
This function does nothing if the thread does not have an event loop.

Upvotes: 1

Related Questions