Results 1 to 8 of 8

Thread: Qt Threading

  1. #1
    Join Date
    May 2008
    Posts
    8
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Windows

    Default Qt Threading

    So, I'm a situation that's similar to the Mandelbrot example that ships with Qt, with a few wrinkles. I'm writing a GUI for a scientific computing application, and it needs to stay responsive while the application is doing something computationally expensive.

    Unlike the Mandelbrot example, where the computationally expensive code appears directly in the worker thread, it has already been implemented and lives in a global object, whose member functions I call in order to interface with that code. I have a QThread subclass, appearing below, that I want to use as a worker thread, and it has some slots that call the global object's troublesome member functions.

    Everything compiles and runs, but, when something happens that triggers one of the QThread's slots, the GUI still goes nonresponsive.

    I think this might be because the GUI also relies on member functions of that global object for various things, or maybe I just have an oversimplified conception of how to use a QThread.

    Regardless, my question is this: how does using a QThread to keep a GUI responsive change when one is calling member functions of a global object like I am attempting to do?

    Qt Code:
    1. class ReconstructionThread : public QThread {
    2. Q_OBJECT
    3.  
    4. public:
    5. ReconstructionThread(QObject* parent) : QThread(parent) {}
    6. void run();
    7.  
    8. public slots:
    9. void startMethod(int iToStart);
    10. void stopMethod(int iToStop);
    11.  
    12. signals:
    13. void methodFinished();
    14. };
    15.  
    16. #include "ReconstructionThread.h"
    17.  
    18. extern ImagingDetectionInterconnect interconnect;
    19.  
    20. void ReconstructionThread::run() {
    21. exec();
    22. }
    23.  
    24. void ReconstructionThread::startMethod(int iToStart) {
    25. interconnect.start(iToStart);//This is the troublemaker, here: it can take an hour
    26. //or two to return
    27. emit methodFinished();
    28. }
    29.  
    30. void ReconstructionThread::stopMethod(int iToStop) {
    31. interconnect.stop(iToStop);
    32. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Qt Threading

    Slots in QThread subclass are troublemakers. QThread object itself lives in the creating thread, not in the thread executed in run(). Please read Multithreading by Brad Hughes, starting from page 33.
    J-P Nurmi

  3. #3
    Join Date
    May 2008
    Posts
    8
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Qt Threading

    Does that mean that member functions of QThread subclasses are also executed in the creating thread?

  4. #4
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Qt Threading

    Exactly. But you can easily work it around by creating another object which lives in the correct thread and move those slots there:
    Qt Code:
    1. class ReconstructionObject : public QObject {
    2. ...
    3. public slots:
    4. void startMethod(int iToStart);
    5. void stopMethod(int iToStop);
    6.  
    7. signals:
    8. void methodFinished();
    9. };
    To copy to clipboard, switch view to plain text mode 
    Then you have two options: 1) create ReconstructionObject in ReconstructionThread::run():
    Qt Code:
    1. void ReconstructionThread::run()
    2. {
    3. ReconstructionObject object;
    4. // connect signals and slots
    5. exec();
    6. }
    To copy to clipboard, switch view to plain text mode 
    or 2) create it somewhere outside and use QObject::moveToThread():
    Qt Code:
    1. ReconstructionThread* thread = new ReconstructionThread(parent);
    2. ReconstructionObject* object = new ReconstructionObject;
    3. object->moveToThread(thread);
    4. thread->start();
    5.  
    6. // and for example something like this to handle cleanup
    7. connect(object, SIGNAL(methodFinished()), object, SLOT(deleteLater()));
    8. connect(object, SIGNAL(destroyed()), thread , SLOT(quit()));
    9. connect(thread, SIGNAL(finished()), thread , SLOT(deleteLater()));
    To copy to clipboard, switch view to plain text mode 
    J-P Nurmi

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

    avh (30th May 2008)

  6. #5
    Join Date
    May 2008
    Posts
    8
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Qt Threading

    So, I understand now more or less how to get interconnect.start(int) executing in the right thread. However, I have one more concern.

    interconnect is a global object, and some of its members will be called elsewhere in my application while waiting for interconnect.start(int) to return. Will that have bad results?

  7. #6
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Qt Threading

    Quote Originally Posted by avh View Post
    So, I understand now more or less how to get interconnect.start(int) executing in the right thread.
    Great!

    Btw, you can use something like:
    Qt Code:
    1. qDebug() << "ReconstructionThread::startMethod():" << QThread::currentThread() << "vs. main thread:" << qApp->thread();
    To copy to clipboard, switch view to plain text mode 
    to output useful information about the current thread.

    However, I have one more concern.

    interconnect is a global object, and some of its members will be called elsewhere in my application while waiting for interconnect.start(int) to return. Will that have bad results?
    Usually it's not a very good idea. You should at least protect data with mutexes to avoid concurrent read and write of same data. But I would rather consider not using a global object at all.
    Last edited by jpn; 30th May 2008 at 20:10.
    J-P Nurmi

  8. #7
    Join Date
    May 2008
    Posts
    8
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Qt Threading

    The global object wasn't my decision; I'm just writing the GUI.

  9. #8
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    6,264
    Thanks
    36
    Thanked 1,519 Times in 1,389 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Qt Threading

    Ok, so then the solution is to make it thread safe with help of mutexes or read-write locks.
    J-P Nurmi

Similar Threads

  1. Correct Threading Technique
    By themusicalguy in forum Qt Programming
    Replies: 10
    Last Post: 2nd November 2007, 14:28
  2. Threading Issue
    By noufalk in forum Qt Programming
    Replies: 4
    Last Post: 4th August 2007, 13:45
  3. Multi threading ...
    By kiranraj in forum Qt Programming
    Replies: 2
    Last Post: 18th June 2007, 16:51
  4. Threading and plotting graph in same program.
    By sar_van81 in forum Qt for Embedded and Mobile
    Replies: 2
    Last Post: 9th May 2007, 20:42
  5. Newbie threading question
    By deepayan in forum Qt Programming
    Replies: 17
    Last Post: 16th April 2007, 00:25

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.