July 13, 2011

rovshanb rovshanb
Lab Rat
9 posts

When to delete QThread

 

Hi,

I have following code in tree model derived from QAbstractItemModel:

  1. void DbTreeModel::populateChildNodes(const QModelIndex & parent)
  2. {
  3.     ... do some prosessing here ...
  4.  
  5.     nodePopulatorThread=new NodePopulatorThread(parent, this);
  6.     connect(nodePopulatorThread, SIGNAL(queryCompleted(DbTreeItemResult)), this, SLOT(nodeListAvailable(DbTreeItemResult)));
  7.     nodePopulatorThread->start();
  8. }

and nodeListAvailable slot looks like this:

  1. void DbTreeModel::nodeListAvailable(const DbTreeItemResult &result)
  2. {
  3.     nodePopulatorThread->wait();
  4.     delete nodePopulatorThread;
  5.     nodePopulatorThread=0;
  6.  
  7.     ... do processing of result ...
  8.  
  9. }

My question is: Is it right to delete thread at the beginning of method, or should I delete it after processing results (because result parameter is created in thread and passed by reference to this slot)? Currently it works OK on Linux, but I think that it can lead to random crashes because data pointed by result parameter may be deleted (when deleting thread) by the time I start to process it. Or am I talking nonsense? ))

Thanks in advance!

10 replies

July 13, 2011

koahnig koahnig
Mad Scientist
2106 posts

There a difference in your code. I guess it should not run this way, because the parameter lists are different.

rovshanb wrote:
  1.     connect(nodePopulatorThread, SIGNAL(queryCompleted(DbTreeItemResult)), this, SLOT(nodeListAvailable(DbTreeItemResult)));
  2.     nodePopulatorThread->start();
  3. }
and here you have a const reference
rovshanb wrote:
  1. void DbTreeModel::nodeListAvailable(const DbTreeItemResult &result)

Otherwise you may adapt the parameter list of your slot method. if you are not using a const reference but a copy it should not be a problem.

If you adapt your connect statement to reflect the use as in your slot method, you are correct about worrying about the life time of your result.

July 13, 2011

changsheng230 changsheng230
Lab Rat
128 posts

Better not delete thread directly, it is very dangerous, use QObject::deleteLater(), which will post an event that will ultimately cause its deletion by the thread the object is living in.

There is a best practice wiki talking about details of good-to-use thread, of course deletion included:
http://developer.qt.nokia.com/wiki/Threads_Events_QObjects

 Signature 

Chang Sheng
常升

July 13, 2011

rovshanb rovshanb
Lab Rat
9 posts

I changed connect method to:

  1. connect(nodePopulatorThread, SIGNAL(queryCompleted(const DbTreeItemResult &)), this, SLOT(nodeListAvailable(const DbTreeItemResult &)));

and moved delete statements to end of method.

But the slot was also firing with the above code (Qt Creator auto suggested it).

So when I write

  1. SLOT(nodeListAvailable(DbTreeItemResult))
and define slot as
  1. DbTreeModel::nodeListAvailable(const DbTreeItemResult &result)
does it work differently than when specifying const & both in connect and slot?

July 13, 2011

rovshanb rovshanb
Lab Rat
9 posts

Ok, thanks for the link, I’ll read it now

July 13, 2011

koahnig koahnig
Mad Scientist
2106 posts

rovshanb wrote:
I changed connect method to:

  1. connect(nodePopulatorThread, SIGNAL(queryCompleted(const DbTreeItemResult &)), this, SLOT(nodeListAvailable(const DbTreeItemResult &)));

and moved delete statements to end of method.

But the slot was also firing with the above code (Qt Creator auto suggested it).

So when I write

  1. SLOT(nodeListAvailable(DbTreeItemResult))
and define slot as
  1. DbTreeModel::nodeListAvailable(const DbTreeItemResult &result)
does it work differently than when specifying const & both in connect and slot?

I do not know. So far I believed that this will result in an error while connecting. Actually it did always give an error message to the console then and returned a false. However, could be just a conclusion on my side. When I did not receive a signal in a slot it was quite often a mismatch of the parameter lists.

July 13, 2011

rovshanb rovshanb
Lab Rat
9 posts

Ok, thank you very much for helping!

July 13, 2011

dakron dakron
Lab Rat
34 posts

You can also make your result item class as implicitly shared object http://doc.qt.nokia.com/4.7-snapshot/implicit-sharing.html [doc.qt.nokia.com] and then you can be sure that you don’t ‘lose’ your results.

July 14, 2011

koahnig koahnig
Mad Scientist
2106 posts

In case someone has similar doubts as expressed above. There has been another thread started Signals/Slots behavior review [developer.qt.nokia.com] detailing the behaviour and the reasoning behind it.

rovshanb wrote:
But the slot was also firing with the above code (Qt Creator auto suggested it).

When the auto suggestions are changing parameter lists may be consiedered as a styling issue then.

August 30, 2011

Luca Luca
Ant Farmer
589 posts

Hi all,
I post my question in this thread to avoid a creation of a new topic.

I have a QObject class:

  1. class GestoreComunicazioneSatellite : public QObject
  2. {
  3.     Q_OBJECT
  4. public:
  5. ...
  6. ...
  7. }
  8.  
  9. GestoreComunicazioneSatellite::GestoreComunicazioneSatellite() :
  10.     QObject(0)
  11. {
  12. ...
  13. m_thread=new QThread();
  14. this->moveToThread(m_thread);
  15. ...
  16. }

The problem is that I get some warning when I destroy the GestoreComunicazioneSatellite object.

I tryed some solution:

  1. GestoreComunicazioneSatellite::~GestoreComunicazioneSatellite()
  2. {
  3. m_thread->deleteLater();
  4. }

I get:
Warning: —> QThread: Destroyed while thread is still running

  1. GestoreComunicazioneSatellite::~GestoreComunicazioneSatellite()
  2. {
  3. m_thread->terminate();
  4. m_thread->wait();
  5. m_thread->deleteLater();
  6. }

I get:
Warning: —> QThread::wait: Thread tried to wait on itself

The only way to avoid warnings is:

  1. GestoreComunicazioneSatellite::~GestoreComunicazioneSatellite()
  2. {
  3. }

but I’m not sure the m_thread is destroyed this way.

What do you think about?

August 30, 2011

Luca Luca
Ant Farmer
589 posts

… and what if I try:

  1. GestoreComunicazioneSatellite::~GestoreComunicazioneSatellite()
  2. {
  3. m_thread->exit(123);
  4. m_thread->deleteLater();
  5. }

?

 
  ‹‹ How to fit multiple images(file1.jpeg,file2.jpeg...) in QTableView’s ItemValue ..?      [solved] SIGSEGV when TCP connection breaks during waitForBytesWritten or waitForReadyRead ››

You must log in to post a reply. Not a member yet? Register here!