Recently ,I come across this problem as I memtioned in this Title. I have tried by using QThread::terminate(),but I just can NOT stop the thread ,which is in a dead loop (let's say,while(1)).
thanks a lot.
You can stop the thread by calling exit() or quit() .
Normally, with Qt you will have a QApplication based class with an event loop with signals and slots, that will not exit from the main function until you want to. In that case you can simply connect the QThread::finish() signal to a slot that checks if all threads are done.
There are two main ways of running code in a separate thread using QThread: subclassing QThread and overriding run(); creating a “worker object” (some QObject subclass) and connecting it to QThread signals.
It seems the only way you can access these is by calling the ( static ) function QThread::currentThreadId() . This returns the id of the currently executing thread, i.e. the thread from which that (static) function is being called.
Terminating the thread is the easy solution to stopping an async operation, but it is usually a bad idea: the thread could be doing a system call or could be in the middle of updating a data structure when it is terminated, which could leave the program or even the OS in an unstable state.
Try to transform your while(1) into while( isAlive() ) and make isAlive() return false when you want the thread to exit.
QThreads can deadlock if they finish "naturally" during termination.
For example in Unix, if the thread is waiting on a "read" call, the termination attempt (a Unix signal) will make the "read" call abort with an error code before the thread is destroyed.
That means that the thread can still reach it's natural exit point while being terminated. When it does so, a deadlock is reached since some internal mutex is already locked by the "terminate" call.
My workaround is to actually make sure that the thread never returns if it was terminated.
while( read(...) > 0 ) {
// Do stuff...
}
while( wasTerminated )
sleep(1);
return;
wasTerminated here is actually implemented a bit more complex, using atomic ints:
enum {
Running, Terminating, Quitting
};
QAtomicInt _state; // Initialized to Running
void myTerminate()
{
if( _state.testAndSetAquire(Running, Terminating) )
terminate();
}
void run()
{
[...]
while(read(...) > 0 ) {
[...]
}
if( !_state.testAndSetAquire(Running, Quitting) ) {
for(;;) sleep(1);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With