When to delete QThread



  • Hi,

    I have following code in tree model derived from QAbstractItemModel:

    @void DbTreeModel::populateChildNodes(const QModelIndex & parent)
    {
    ... do some prosessing here ...

    nodePopulatorThread=new NodePopulatorThread(parent, this);
    connect(nodePopulatorThread, SIGNAL(queryCompleted(DbTreeItemResult)), this, SLOT(nodeListAvailable(DbTreeItemResult)));
    nodePopulatorThread->start();
    

    }@

    and nodeListAvailable slot looks like this:

    @void DbTreeModel::nodeListAvailable(const DbTreeItemResult &result)
    {
    nodePopulatorThread->wait();
    delete nodePopulatorThread;
    nodePopulatorThread=0;

    ... do processing of result ...
    

    }@

    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!


  • Moderators

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

    [quote author="rovshanb" date="1310553943"]
    @ connect(nodePopulatorThread, SIGNAL(queryCompleted(DbTreeItemResult)), this, SLOT(nodeListAvailable(DbTreeItemResult)));
    nodePopulatorThread->start();
    }@
    [/quote]
    and here you have a const reference
    [quote author="rovshanb" date="1310553943"]
    @
    void DbTreeModel::nodeListAvailable(const DbTreeItemResult &result) @
    [/quote]

    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.



  • 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



  • I changed connect method to:

    @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 @SLOT(nodeListAvailable(DbTreeItemResult))@ and define slot as @DbTreeModel::nodeListAvailable(const DbTreeItemResult &result)@ does it work differently than when specifying const & both in connect and slot?



  • Ok, thanks for the link, I'll read it now


  • Moderators

    [quote author="rovshanb" date="1310554925"]I changed connect method to:

    @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 @SLOT(nodeListAvailable(DbTreeItemResult))@ and define slot as @DbTreeModel::nodeListAvailable(const DbTreeItemResult &result)@ does it work differently than when specifying const & both in connect and slot?[/quote]

    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.



  • Ok, thank you very much for helping!



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


  • Moderators

    In case someone has similar doubts as expressed above. There has been another thread started "Signals/Slots behavior review":http://developer.qt.nokia.com/forums/viewthread/7771/ detailing the behaviour and the reasoning behind it.

    [quote author="rovshanb" date="1310554925"]
    But the slot was also firing with the above code (Qt Creator auto suggested it).
    [/quote]

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



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

    I have a QObject class:
    @
    class GestoreComunicazioneSatellite : public QObject
    {
    Q_OBJECT
    public:
    ...
    ...
    }

    GestoreComunicazioneSatellite::GestoreComunicazioneSatellite() :
    QObject(0)
    {
    ...
    m_thread=new QThread();
    this->moveToThread(m_thread);
    ...
    }
    @

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

    I tryed some solution:
    @
    GestoreComunicazioneSatellite::~GestoreComunicazioneSatellite()
    {
    m_thread->deleteLater();
    }
    @
    I get:
    Warning: --> QThread: Destroyed while thread is still running

    @
    GestoreComunicazioneSatellite::~GestoreComunicazioneSatellite()
    {
    m_thread->terminate();
    m_thread->wait();
    m_thread->deleteLater();
    }
    @
    I get:
    Warning: --> QThread::wait: Thread tried to wait on itself

    The only way to avoid warnings is:
    @
    GestoreComunicazioneSatellite::~GestoreComunicazioneSatellite()
    {
    }
    @

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

    What do you think about?



  • ... and what if I try:
    @
    GestoreComunicazioneSatellite::~GestoreComunicazioneSatellite()
    {
    m_thread->exit(123);
    m_thread->deleteLater();
    }
    @

    ?


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.