Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I terminate a QThread

Tags:

qt

qthread

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.

like image 475
user230938 Avatar asked Dec 14 '09 02:12

user230938


People also ask

How do you destroy a QThread in Python?

You can stop the thread by calling exit() or quit() .

How do you wait for QThread to finish?

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.

How do you run a function in QThread?

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.

How do I find my QThread ID?

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.


2 Answers

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.

like image 88
rpg Avatar answered Oct 15 '22 08:10

rpg


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);
  }
}
like image 37
hmn Avatar answered Oct 15 '22 07:10

hmn