我该如何终止QThread

时间:2009-12-14 02:23:15

标签: qt qthread

最近,我在本标题中记得这个问题。 我尝试过使用QThread :: terminate(),但我无法停止 线程,它处于一个死循环中(比方说,while(1))。

非常感谢。

5 个答案:

答案 0 :(得分:12)

终止线程是停止异步操作的简单解决方案,但通常是一个坏主意:线程可能正在进行系统调用,或者在终止时可能正在更新数据结构,这可能是让程序甚至操作系统处于不稳定状态。

尝试将while(1)转换为while(isAlive())并使isAlive()在您希望线程退出时返回false。

答案 1 :(得分:1)

QThreads如果在终止期间“自然地”完成就会陷入僵局。

例如在Unix中,如果线程正在等待“读取”调用,则终止尝试(Unix信号)将使“读取”调用在线程被销毁之前用错误代码中止。

这意味着线程在终止时仍然可以到达它的自然出口点。当它这样做时,由于某些内部互斥锁已被“终止”调用锁定,因此会发生死锁。

我的解决方法是确保线程从不在终止后返回。

while( read(...) > 0 ) {

  // Do stuff...
}

while( wasTerminated )
  sleep(1);

return;

wasTerminated 这里使用原子注入实际上实现起来有点复杂:

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

答案 2 :(得分:0)

您是否尝试过exitquit

答案 3 :(得分:0)

线程是否致电QThread::setTerminationEnabled(false)?这将导致线程终止无限期地延迟。

编辑:我不知道你在哪个平台,但我检查了QThread :: terminate的Windows实现。假设线程实际上正在运行,并且未通过上述函数禁用终止,它基本上是Windows API中TerminateThread()的包装器。这个函数接受来自无线程的不尊重,并且往往会在资源泄漏和类似的悬空状态下留下混乱。如果它没有杀死线程,你要么处理僵尸内核调用(很可能是阻塞的I / O),要么在某个地方遇到更大的问题。

答案 4 :(得分:0)

使用未命名的管道

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

如果您打算创建管道,请使用

if( pipe(gPipeFdTest) < 0)

{

perror("Pipe failed");

exit(1);

}

上面的代码将创建一个管道,其两端有gPipeFdTest [0]用于读取,gPipeFdTest [1]用于写入。你可以做的是在你的运行功能设置中使用select系统调用来读取管道。从您想要运行的地方开始,设置使用写入系统调用进行写入。我已经使用select系统调用来监视管道的读取端,因为它适合我的实施。试着在你的情况下找出所有这些。如果您需要更多帮助,请给我一个嗡嗡声。

编辑:

我的问题和你的一样。我有一段时间(1)循环和我尝试的其他东西需要互斥和其他花哨的多线程mumbo jumbo,这增加了复杂性和调试是噩梦。除了简化代码之外,使用管道使我从这些复杂性中解脱出来。我并不是说这是最好的选择,但就我而言,事实证明它是最好和最干净的选择。在此解决方案之前,我被窃听了我的应用程序。