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

Mik*_*ail 0 qt qthread

当我的应用程序被销毁时,我想终止(完成)QThread.因此,我调用terminate()quit()destructor从'我的QThread的派生类.安全吗?

class Session : public QThread
{
    Q_OBJECT

private:
    CheckerAdapter *inst;

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

    ~Session(){
        terminate();
        quit();
    }
};
Run Code Online (Sandbox Code Playgroud)

Mik*_*ike 5

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

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

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

  • 如果您的线程运行一个事件循环(即您不覆盖run(),或者如果您调用exec()自定义run()实现),您可以从任何线程调用QThread::quit()/QThread::exit().这将导致线程事件的循环在完成处理当前事件后立即返回.没有数据损坏,因为当前处理不会终止.
  • 如果您的线程没有运行事件循环,您可以使用QThread::requestInterruption()任何其他线程告诉线程它应该停止.但是你必须在你的run()使用实现中处理它isInterruptionRequested()(否则,调用requestInterruption()将什么也不做).

注意:

如果您使用上述任何方法来停止QThread其析构函数,则必须确保在QThread对象被破坏后该线程不再运行,您可以在使用/ 后调用QThread::wait().quit()requestInterruption()

看看这个QThread子类的类似实现的答案.