0

我正在尝试在我的 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 上出现分段错误。

4

2 回答 2

3

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

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

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

所以,不要子类化QThread. 您可以只使用标准事件循环和信号槽系统来使用您的线程。您还可以使用更高级的界面,例如QRunnable是否可以为您的任务完成。

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

于 2013-06-05T09:18:36.637 回答
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.
于 2013-06-05T06:07:46.047 回答