停止QThread执行

时间:2013-06-05 05:20:20

标签: qt timeout qthread

我正在尝试在QT应用程序中实现超时。我已经使用QThread来执行操作(需要超时的任务)并使用QElapsedTimer来计算等待执行操作所经过的时间。以下是代码段

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

现在,如果任务未完成且超时发生,我会“在线程仍在运行时被销毁”并且应用程序崩溃了。 我试图调用QThread的terminate()函数,但它在Windows上运行但是在Linux上我遇到了分段错误。

2 个答案:

答案 0 :(得分:3)

您已经提到quit()不适用于您的线程,因此我认为您已重新实现QThread::run方法,并且在您的实现中不使用事件循环。正如文档所说:

  

从QThread开始,大多数用途都不需要对QThread进行子类化   提供全功能的线程管理功能。尽管如此,   如果您希望实现高级线程,可以将QThread子类化   管理。这是通过添加新的成员函数来完成的   子类,和/或重新实现run()。 QThread的run()函数是   类似于应用程序的main()函数 - 它在执行时执行   线程启动,线程返回时结束。

     

注意:在Qt 4.4之前,使用QThread进行并行的唯一方法   处理是将其子类化并在其中实现处理代码   跑()。这种方法现在被认为是不良做法;一个QThread应该   只管理一个线程,而不是处理数据。

所以,不要继承QThread。您可以使用标准事件循环和信号槽系统来使用您的线程。如果可以为您的任务完成,您还可以使用更高级别的界面,例如QRunnable

如果您确定要重新实现QThread::run并消除事件循环的优点,那么您应该注意手动停止线程。例如,您可以使用一些布尔标志bool need_to_stop并在线程运行时定期检查其值。当您决定停止该线程时,将该标志的值设置为true,然后调用QThread::wait()。当QThread::run由于标志值而完成时,您的线程将被停止并且wait()将返回。但请注意,您不能简单地同时使用新线程和GUI线程中的一个标志。您需要一些同步机制,如QMutex。所以,这件事情过于复杂。如果你不想做一些非常低级的事情,就不要继承QThread。

答案 1 :(得分:1)

尝试使用文档

中提到的void QThread::quit ()
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.