Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Qt: qthread destroyed while thread is still running during closing

I have a class:

class centralDataPool : public QObject
{
    Q_OBJECT
public:
    centralDataPool(QObject * parent = 0);
    ~centralDataPool();
    commMonitor commOverWatch;

private:
    QThread monitorThread;
    int totalNum;

signals:
    void createMonitor(int);
};

In its constructor I did:

centralDataPool::centralDataPool(QObject* parent) : QObject(parent),totalNum(0)
{
    connect(this, SIGNAL(createMonitor(int)), &commOverWatch, SLOT(createMonitor(int)));
    commOverWatch.moveToThread(&monitorThread);
    monitorThread.start();
}

when I called the destructor of this class I get the error message:

qthread destroyed while thread is still running

But when I tried to terminate the monitorThread in the destructor of class centralDataPool,

centralDataPool::~centralDataPool()
{
    monitorThread.terminate();
}

I get memory leakage.

What is the correct way to terminate a thread during the destruction of its owner object ?

like image 701
Nyaruko Avatar asked Feb 22 '15 17:02

Nyaruko


1 Answers

You should note that if you have a loop running in a function of your thread, you should explicitly end it in order to properly terminate the thread.

You can have a member variable in your class named finishThread which should be set to true when the application is going to close. Just provide a slot in which you set the value for finishThread. When you want to terminate the thread emit a signal that is connected to that slot with a true value. finishThread should be provided in the loop condition to end it when it is set to true. After that wait for the thread to finish properly for some seconds and force it to terminate if it did not finish.

So you can have in your destructor :

emit setThreadFinished(true); //Tell the thread to finish
monitorThread->quit();
if(!monitorThread->wait(3000)) //Wait until it actually has terminated (max. 3 sec)
{
    monitorThread->terminate(); //Thread didn't exit in time, probably deadlocked, terminate it!
    monitorThread->wait(); //We have to wait again here!
}
like image 157
Nejat Avatar answered Oct 21 '22 12:10

Nejat