Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Deleting object in QThread
Forum Updated to NodeBB v4.3 + New Features

Deleting object in QThread

Scheduled Pinned Locked Moved General and Desktop
8 Posts 4 Posters 8.0k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    bobdark
    wrote on 5 Jan 2015, 14:10 last edited by
    #1

    Hi all,

    I'm using the worker-object approach, and I would like to understand once and for all, what is the proper way to release resources that live in another thread and --what exactly happens there?!--.
    So, this is the sketch of my code's structure (any comments regarding improving the structure are of course wellcommed - I'm using Qt::BlockingQueuedConnection on purpose, because there are multiple worker objects and I want their creation and initialization order to be precise):

    @class Worker : QObject
    {
    Q_OBJECT

    public:
    Worker()

    {/*initialization code:
    init timer and connect its signal to worker */
    }

    ~Worker(){}

    public slots:
    void startWorker()
    {
    if (QThread::currentThread() == this->thread())
    doActualStart();
    else
    QMetaObject::invokeMethod(this, "doActualStart", Qt::BlockingQueuedConnection);
    }

    void stopWorker()
    {
    if (QThread::currentThread() == this->thread())
    doActualClose();
    else
    QMetaObject::invokeMethod(this, "doActualClose", Qt::BlockingQueuedConnection);
    }

    private slots:
    void doActualStart()
    {
    //start timer
    }

    void doActualClose()
    {
    //stop timer
    }

    void timerSlot()
    {
    //do Logic
    }

    private:
    m_Timer;
    };

    class Manager
    {
    /Lives in main thread/

    void createWorker()
    {
    Worker* worker = new Worker();
    QThread* workerThread = new QThread();

    worker->moveToThread(workerThread());
    connect(worker, SIGNAL(destroyed()), workerThread, SLOT(quit()));

    workerThread->start();
    worker->startWorker();
    }

    void deleteWorker(Worker* worker)
    {
    //aquire worker thread
    QThread* workerThread = /non trivial aquisition code, since worker->thread() returns const/;

    worker->stopWorker();
    QMetaObjectInvoke(worker, "deleteLater", Qt::BlockingQueuedConnection);

    workerThread->wait();
    }

    };@

    My questions:

    1. When calling deleteWorker(w), the application hangs on workerThread->wait(); Does this mean that the worker project does not get deleted for some reason? or maybe the problem is somehow related to connection type of destroyed() to quit() connection?

    2. What is the proper way to delete resources after moving them to a QThread object? In worker-object examples,
      I saw the next code:

    @connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
    connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
    connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));@

    So what exactly happens when worker emits finished()? Is the worker object supposed to be deleted from a specific thread? or it may be deleted from the main thread or the worker thread, depending on when the thread object quits its event loop?

    Thanks in advance

    1 Reply Last reply
    0
    • C Offline
      C Offline
      ckakman
      wrote on 5 Jan 2015, 14:47 last edited by
      #2

      Hi,

      1. QObject:deleteLater() schedules a delete operation, it doesn't delete the object, therefore you don't need to call deleteLater() the way you do. worker->deleteLater() would suffice. That behavior of deleteLater() also explains why your blocking call doesn't block the main thread: deleteLater() returns without blocking.

      If the worker thread is idle, I don't see any reason why workerThread->wait() would block for so lang that you notice it. The QObject::destroyed() signal should make the thread exit its event loop.

      1. You should strive to delete a QObject in the thread it lives. This is important when you have QTimers, QTcpSockets etc.

      I would prefer the following chain of messages to delete a QObject instance living in a QThread other than the main thread:
      @
      connect( object, SIGNAL(destroyed), thread, SLOT(quit()) );
      connect( thread, SIGNAL(finished()), thread, SLOT(deleteLater()) );
      @

      And I would do the following in the main thread:
      @
      object->deleteLater();
      thread->wait();
      @

      If you are care about destructing all your objects properly when main() returns, than don't forget to give a parent to QThread objects, because the main event loop may exit before the delete operation scheduled by QThread::deleteLater() is executed.

      1 Reply Last reply
      0
      • B Offline
        B Offline
        bobdark
        wrote on 5 Jan 2015, 16:28 last edited by
        #3

        I understood what caused the application to hang - the problem was, as I assumed, with

        @connect(worker, SIGNAL(destroyed()), workerThread, SLOT(quit));@

        Since these two objects live in different threads, Qt::QueuedConnection type is used, which means when worker object is deleted, the event is posted to the main thread's event loop. When the control returns to the main thread, the call to workerThread->wait() is made before the main thread got a chance to process the event that was posted because of worker deletion.

        If I add for example (Not that I promote such approach, its for demonstration purposes only)

        @worker->stopWorker();
        QMetaObjectInvoke(worker,"deleteLater",Qt::BlockingQueuedConnection);
        QCoreApplication::processEvents(QEventLoop::AllEvents, 10000);

        workerThread()->wait();@

        Then the worker thread quits quietly and everything is ok...

        1 Reply Last reply
        0
        • C Offline
          C Offline
          ckakman
          wrote on 5 Jan 2015, 17:43 last edited by
          #4

          You are right. Just add workerThread->quit() before workerThread->wait() . And worker->deleteLater() before that.

          1 Reply Last reply
          0
          • B Offline
            B Offline
            bobdark
            wrote on 6 Jan 2015, 14:06 last edited by
            #5

            But how can I be sure that the worker thread doesn't quit before processing worker's deleteLater event? Before the thread quits its event loop, does it make sure it processes all deleteLater events?

            1 Reply Last reply
            0
            • R Offline
              R Offline
              Resurrection
              wrote on 6 Jan 2015, 14:17 last edited by
              #6

              [quote author="bobdark" date="1420553165"]But how can I be sure that the worker thread doesn't quit before processing worker's deleteLater event? Before the thread quits its event loop, does it make sure it processes all deleteLater events?[/quote]

              Yes it does.

              Secrets are power.

              1 Reply Last reply
              0
              • JKSHJ Offline
                JKSHJ Offline
                JKSH
                Moderators
                wrote on 6 Jan 2015, 14:34 last edited by
                #7

                From the "QThread documentation":http://doc.qt.io/qt-5/qthread.html#managing-threads --

                [quote]From Qt 4.8 onwards, it is possible to deallocate objects that live in a thread that has just ended, by connecting the finished() signal to QObject::deleteLater().[/quote]

                Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                1 Reply Last reply
                0
                • B Offline
                  B Offline
                  bobdark
                  wrote on 6 Jan 2015, 14:54 last edited by
                  #8

                  Awesome, thanks

                  1 Reply Last reply
                  0

                  1/8

                  5 Jan 2015, 14:10

                  • Login

                  • Login or register to search.
                  1 out of 8
                  • First post
                    1/8
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved