Results 1 to 6 of 6

Thread: Thread event loop not working when the main application is blocked.

  1. #1
    Join Date
    Mar 2006
    Posts
    56
    Thanks
    7
    Thanked 3 Times in 2 Posts
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Thread event loop not working when the main application is blocked.

    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/...oing-it-wrong/
    The object is created the following way


    Qt Code:
    1. MainDialog::MainDialog(QWidget *parent, Qt::WindowFlags f)
    2. : QDialog(parent, f)
    3. {
    4. /* ... */
    5.  
    6. myThread = new QThread(this);
    7.  
    8. myObject = new MyObject;
    9. myObject->moveToThread(myThread);
    10.  
    11. connect( myThread, SIGNAL( started() ),
    12. myObject, SLOT( start() ) );
    13. connect( myObject, SIGNAL( finished() ),
    14. myThread, SLOT( quit() ) );
    15. }
    To copy to clipboard, switch view to plain text mode 

    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

    Qt Code:
    1. void MyObject::start()
    2. {
    3. QTimer::singleShot( 0, this, SLOT(doOperation()) );
    4. }
    5.  
    6. void MyObject::doOperation()
    7. {
    8. if( stopped() )
    9. {
    10. emit finished();
    11. return;
    12. }
    13.  
    14. /* ... */
    15.  
    16. QTimer::singleShot(1000, this, SLOT(doOperation()));
    17. }
    18.  
    19. void MyObject::stop()
    20. {
    21. QMutexLocker ml(&_mutex);
    22.  
    23. _stopped = true;
    24. }
    25.  
    26. bool MyObject::stopped() const
    27. {
    28. QMutexLocker ml(&_mutex);
    29.  
    30. return _stopped;
    31. }
    To copy to clipboard, switch view to plain text mode 


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

    Qt Code:
    1. void MainDialog::onStartClicked()
    2. {
    3. myThread->start();
    4. }
    To copy to clipboard, switch view to plain text mode 

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

    Qt Code:
    1. void MainDialog::onStopClicked()
    2. {
    3. myObject->stop();
    4.  
    5. myThread->wait();
    6.  
    7. /* ... */
    8. }
    To copy to clipboard, switch view to plain text mode 

    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.
    Last edited by kalos80; 7th February 2012 at 15:07.

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Thread event loop not working when the main application is blocked.

    This is because the thread object lives in the main thread and not the thread it represents. Thus if you emit a signal connected to the quit() slot, the call is queued so that it can be executed in the main thread. But since you call wait() in the main thread, the slot never has a chance to execute because the main thread is already locked by wait(). A solution is to either not call wait() at all (as it is not required) and instead simply connect the finished() signal to the deleteLater() slot or not call wait() in the onStopClicked() slot but instead connect a custom slot to the finished() signal and call wait() from that slot.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Mar 2006
    Posts
    56
    Thanks
    7
    Thanked 3 Times in 2 Posts
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Thread event loop not working when the main application is blocked.

    wysota, thanks for your reply.

    This is because the thread object lives in the main thread and not the thread it represents. Thus if you emit a signal connected to the quit() slot, the call is queued so that it can be executed in the main thread. But since you call wait() in the main thread, the slot never has a chance to execute because the main thread is already locked by wait().
    I still do not understand why, since the QThread has its own event loop and since I move myObject to the thread, so I change its thread affinity, the events launched by myObject are handled by the event loop of the main thread and not by the event loop of the thread the object belongs to.

    A solution is to either not call wait() at all (as it is not required) and instead simply connect the finished() signal to the deleteLater() slot
    I need to wait the thread effectively finishes because I need to do some operations only after the thread has been stopped. I did not write them on the example code for simplicity reasons.

    not call wait() in the onStopClicked() slot but instead connect a custom slot to the finished() signal and call wait() from that slot.
    that could work, but consider the following case where I need to stop the thread when the application is closed

    Qt Code:
    1. void MainDialog::closeEvent(QCloseEvent *ce)
    2. {
    3. myObject->stop();
    4. }
    5.  
    6. void MainDialog::waitForOpFinished()
    7. {
    8. myObject->wait();
    9.  
    10. /* ..... */
    11. }
    To copy to clipboard, switch view to plain text mode 

    I can not perform a wait on another slot, because since the application is being closed that slot could not be called

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Thread event loop not working when the main application is blocked.

    Quote Originally Posted by kalos80 View Post
    I still do not understand why, since the QThread has its own event loop
    No, the thread has its own event loop, not the QThread object. You didn't move the QThread object to the new thread but some other object. Hence all events for the QThread instance are handled by the thread that created the object (aka the main thread).

    I can not perform a wait on another slot
    Sure you can.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. The following user says thank you to wysota for this useful post:

    kalos80 (8th February 2012)

  6. #5
    Join Date
    Mar 2006
    Posts
    56
    Thanks
    7
    Thanked 3 Times in 2 Posts
    Qt products
    Qt3 Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Thread event loop not working when the main application is blocked.

    The thread has its own event loop, not the QThread object. You didn't move the QThread object to the new thread but some other object. Hence all events for the QThread instance are handled by the thread that created the object (aka the main thread).
    Ahhhh, that would explain everything. So the event loop of myThread object is the main thread event loop, while the thread event loop processes events of thread's objects.
    Thank you very much for making me see the light


    Sure you can.
    My point is, since the finished() signal could be emitted when the the application is being closed, I'm not sure that all events in queue are processed before the application is closed, so the waitForOpFinished() slot could not be called.

    I fixed the problem calling the thread quit() directly from the object

    Qt Code:
    1. void MyObject::doOperation()
    2. {
    3. if( stopped() )
    4. {
    5. emit finished();
    6.  
    7. thread()->quit();
    8.  
    9. return;
    10. }
    To copy to clipboard, switch view to plain text mode 

  7. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Thread event loop not working when the main application is blocked.

    Quote Originally Posted by kalos80 View Post
    My point is, since the finished() signal could be emitted when the the application is being closed, I'm not sure that all events in queue are processed before the application is closed, so the waitForOpFinished() slot could not be called.
    When quit is requested you can first stop the thread and only when it's already done, quit() the main event loop.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


Similar Threads

  1. simple console application does ot finish
    By szisziszilvi in forum Newbie
    Replies: 4
    Last Post: 9th January 2012, 11:22
  2. Pausing a thread while waiting that phonon play a sound file
    By franco.amato in forum Qt Programming
    Replies: 1
    Last Post: 21st March 2011, 21:41
  3. GUI freezes in loop: Thread does not help?
    By Matty23 in forum Qt Programming
    Replies: 4
    Last Post: 25th November 2010, 21:04
  4. Waiting on a thread?
    By MrGarbage in forum Qt Programming
    Replies: 1
    Last Post: 3rd November 2007, 16:13
  5. My SDI application freezes when it is inactive ...why ?
    By yellowmat in forum Qt Programming
    Replies: 1
    Last Post: 5th September 2006, 16:37

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.