从QThread派生的类的析构函数手动调用terminate()和quit()是否安全?

时间:2017-01-16 11:01:03

标签: qt qthread

当我的应用程序被销毁时,我想终止(完成)QThread。 所以我在`QThread的terminate()派生类中调用了quit()destructor。 这样安全吗?

class Session : public QThread
{
    Q_OBJECT

private:
    CheckerAdapter *inst;

public:
    explicit Session(CheckerAdapter *inst, QObject *parent = 0);
    void run();

    ~Session(){
        terminate();
        quit();
    }
};

1 个答案:

答案 0 :(得分:5)

使用QThread::terminate()会导致内存损坏,因为线程在不知情的情况下被终止,它可以在终止时执行任何操作:

  

警告:此功能很危险,不鼓励使用。线程可以在其代码路径中的任何位置终止。修改数据时可以终止线程。线程无法自行清理,解锁任何保持的互斥锁等。简而言之,只有在绝对必要时才使用此功能。

要安全地终止QThread,您需要有一种方法告诉线程它必须终止,并且当线程得到它时,它应该尽快从其run()实现返回可能。 Qt提供了两种方法:

  • 如果您的主题运行事件循环(即您没有覆盖run(),或者如果您在自定义exec()实施中致电run()您可以从任意线程致电QThread::quit() / QThread::exit()。这将导致线程事件的循环在完成处理当前事件后立即返回。没有数据损坏,因为当前处理不会终止。
  • 如果您的线程未运行事件循环您可以使用来自任何其他线程的QThread::requestInterruption() 来告知线程它应该停止。 但您必须使用isInterruptionRequested() run()的实施中处理此问题(否则,调用requestInterruption()将无效)。

注意:

如果您使用上述任何方法在其析构函数中停止QThread必须确保在QThread对象被破坏后该线程不再运行< / strong>,您可以在使用quit() / requestInterruption()致电QThread::wait() 来实现这一目标。

有关QThread子类的类似实现,请查看this answer