我正在尝试在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上我遇到了分段错误。
答案 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.