Reputation: 1086
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
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
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