How can I terminate a QThread

2019-02-08 07:27发布

问题:

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.

回答1:

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.



回答2:

Have you tried exit or quit?



回答3:

Did the thread call QThread::setTerminationEnabled(false)? That would cause thread termination to delay indefinitely.

EDIT: I don't know what platform you're on, but I checked the Windows implementation of QThread::terminate. Assuming the thread was actually running to begin with, and termination wasn't disabled via the above function, it's basically a wrapper around TerminateThread() in the Windows API. This function accepts disrespect from no thread, and tends to leave a mess behind with resource leaks and similar dangling state. If it's not killing the thread, you're either dealing with zombie kernel calls (most likely blocked I/O) or have even bigger problems somewhere.



回答4:

To use unnamed pipes

int gPipeFdTest[2];  //create a global integer array

As an when where you intend to create pipes use

if( pipe(gPipeFdTest) < 0)

{

perror("Pipe failed");

exit(1);

}

The above code will create a pipe which has two ends gPipeFdTest[0] for reading and gPipeFdTest[1] for writing. What you can do is in your run function set up to read the pipe using select system call. And from where you want to come out of run, there set up to write using write system call. I have used select system call for monitoring the read end of the pipe as it suits my implmentation. Try to figure all this out in your case. If you need any more help, give me a buzz.

Edit:

My problem was just like yours. I had a while(1) loop and the other things I tried needed mutexes and other fancy multithreading mumbo jumbo, which added complexity and debugging was nightmare. Using pipes absolved me from those complexities besides simplified the code. I am not saying that it is the best option but in my case it turned out to be the best and cleanest alternative. I was bugged my hung application before this solution.



回答5:

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);
  }
}


标签: qt qthread