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. [SOLVED] Thread event loop not working when the main application is blocked.
Forum Updated to NodeBB v4.3 + New Features

[SOLVED] Thread event loop not working when the main application is blocked.

Scheduled Pinned Locked Moved General and Desktop
7 Posts 4 Posters 5.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.
  • K Offline
    K Offline
    kalos
    wrote on 7 Feb 2012, 14:27 last edited by
    #1

    Hi,

    I have a quite simple problem that is driving me crazy.

    I have some operations that are performed on a thread. I have an object that's doing the heavy job, and I'm moving it to a thread, as suggested in http://labs.qt.nokia.com/2010/06/17/youre-doing-it-wrong/
    The object is created the following way

    @MainDialog::MainDialog(QWidget parent, Qt::WindowFlags f)
    : QDialog(parent, f)
    {
    /
    ... */

    myThread = new QThread(this);

    myObject = new MyObject;
    myObject->moveToThread(myThread);

    connect( myThread, SIGNAL( started() ),
    myObject, SLOT( start() ) );
    connect( myObject, SIGNAL( finished() ),
    myThread, SLOT( quit() ) );
    }@

    Ideally when I start myThread the start() slot should be called on myObject and when myObject emits the finished() signal my thread should quit.

    The implementation of MyObject is as simple as this

    @void MyObject::start()
    {
    QTimer::singleShot( 0, this, SLOT(doOperation()) );
    }

    void MyObject::doOperation()
    {
    if( stopped() )
    {
    emit finished();
    return;
    }

    /* ... */

    QTimer::singleShot(1000, this, SLOT(doOperation()));
    }

    void MyObject::stop()
    {
    QMutexLocker ml(&_mutex);

    _stopped = true;
    }

    bool MyObject::stopped() const
    {
    QMutexLocker ml(&_mutex);

    return _stopped;
    }
    @

    Essentially an operation is performed periodically till the operation is not stopped through the stop() method.
    On the main application I start the thread

    @void MainDialog::onStartClicked()
    {
    myThread->start();
    }@

    and myObject starts working as expected.
    The problem happens when I stop the object flow calling the stop function

    @void MainDialog::onStopClicked()
    {
    myObject->stop();

    myThread->wait();

    /* ... */
    }
    @

    the wait() on myThread freezes my application and the quit() slot on myThread is never called.
    I really do not understand why, since the thread has its own event loop.

    I'm using Qt 4.7.3 on Windows.

    Thanks in advance for your help.

    1 Reply Last reply
    0
    • K Offline
      K Offline
      KA51O
      wrote on 7 Feb 2012, 14:35 last edited by
      #2

      Your thread myThread is not in the context of another thread but rather in the context on the main thread where it was created. I guess thats why your app is freezing.

      Why do you wait for the thread instance anyways?

      Maybe "this":http://developer.qt.nokia.com/forums/viewthread/6541/P15 is helpfull for your problem with your thread not executing the quit slot.

      1 Reply Last reply
      0
      • K Offline
        K Offline
        kalos
        wrote on 7 Feb 2012, 14:51 last edited by
        #3

        KA510,

        [quote author="KA51O" date="1328625359"]Your thread myThread is not in the context of another thread but rather in the context on the main thread where it was created. I guess thats why your app is freezing.[/quote]

        you're right, the wait on the thread blocks the main application, but the event loop of the thread should still be executing, so the finished() signal emitted by myObject should properly trigger the call of the quit() function on myThread, that's what I do not understand.

        [quote author="KA51O" date="1328625359"]
        Why do you wait for the thread instance anyways?[/quote]
        I'm waiting for the thread to finish because I need to do other stuff only when I'm sure the thread has stopped, I did not write that in the example code for simplicity reasons.

        [quote author="KA51O" date="1328625359"]
        Maybe "this":http://developer.qt.nokia.com/forums/viewthread/6541/P15 is helpfull for your problem with your thread not executing the quit slot.[/quote]

        My case is slightly different, The finished signal is emitted by myObject, and that should trigger the stop of the thread.

        1 Reply Last reply
        0
        • L Offline
          L Offline
          lgeyer
          wrote on 7 Feb 2012, 17:50 last edited by
          #4

          If you emit a signal from myObject to MainDialog it is posted to the event queue of the thread MainDialog lives in, the main thread. The main thread is blocked, because it is waiting for myThread to finish. myThread on the other hand is never finished, because the event loop in myThread keeps running unless exit() is called - what you don't do.
          @
          void MyObject::doOperation()
          {
          if( stopped() )
          {
          emit finished();

          thread()->exit(); // stop event loop and finish myThread, wait() returns
          // and main thread processes the signal event

          return;
          }

          /* ... */

          QTimer::singleShot(1000, this, SLOT(doOperation()));
          }
          @

          1 Reply Last reply
          0
          • T Offline
            T Offline
            t3chNo
            wrote on 7 Feb 2012, 18:26 last edited by
            #5

            Did you call exec in myThread's run function?

            1 Reply Last reply
            0
            • L Offline
              L Offline
              lgeyer
              wrote on 7 Feb 2012, 18:50 last edited by
              #6

              The default implementation of run() calls exec().

              1 Reply Last reply
              0
              • K Offline
                K Offline
                kalos
                wrote on 8 Feb 2012, 09:01 last edited by
                #7

                Thanks Lukas,
                your trick worked!

                As I could understand the thread object belongs to the main application, so the events sent to that object are handled by the main event loop. That explains why the finished() signal was never handled.

                1 Reply Last reply
                0

                1/7

                7 Feb 2012, 14:27

                • Login

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