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. QThread, How To Really, Truly Use
Qt 6.11 is out! See what's new in the release blog

QThread, How To Really, Truly Use

Scheduled Pinned Locked Moved General and Desktop
10 Posts 4 Posters 6.6k Views 4 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.
  • D Offline
    D Offline
    deleted28
    wrote on last edited by
    #1

    Hello,
    i tried to get an answer from Maya but maybe my question is too stupid :)
    I do not really understand this sentence from

    By the way, one extremely important thing to note here is that you should NEVER allocate heap objects (using new) in the constructor of the QObject class as this allocation is then performed on the main thread and not on the new QThread instance, meaning that the newly created object is then owned by the main thread and not the QThread instance. 
    

    Link: http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/

    If i create a new default qt application using the wizzard I get the Mainwindow constructor, the other constructor I have is the WORKERS constructor.

    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        QThread* thread = new QThread;
        Worker* worker = new Worker();
        worker->moveToThread(thread);
    ...
    

    Where exactly i NEVER should create the Thread and Worker instance ?
    Can do as in the MainWindow constructor above (in this simple code it works).
    Maybe someone has a complete little project how to do and how NEVER do.
    thx

    JKSHJ 1 Reply Last reply
    0
    • K Offline
      K Offline
      koahnig
      wrote on last edited by koahnig
      #2

      Hi,
      I had seen already your reponse to the origioal thread of Maya. There I wondered already if you should stick too closely to what is written there. The summary has been created when there was Qt4 something. We have typically Qt 5 already. Therefore, a couple of things might have changed.
      Also if something was completely wrong in documentation back for Qt 4, it is likely that that has been corrected.
      Since there has been no followup for Qt5 based on the original summary, IMHO, I would rather rely more on current documentations (e.g. this) as a start. There are many different articles in the documentation, which certainly do not really make it less complex.

      Vote the answer(s) that helped you to solve your issue(s)

      1 Reply Last reply
      0
      • D Offline
        D Offline
        deleted28
        wrote on last edited by deleted28
        #3

        thnaks for reply. Yes, I use the actual docs (5.5).

        But did you understand this "NEVER"-sentence. Which constructor Maya meant
        in which never put the "new" commands ?
        The Workers constructor (make no sense for me at all)
        or
        the MainWindow constructor (what i did and works).
        If not in MainWindow constructor where else ?
        Or do you have an complete simple example how to or how never do it.

        1 Reply Last reply
        0
        • K Offline
          K Offline
          koahnig
          wrote on last edited by
          #4

          No. I am not really in details of threading yet.

          It might have something to do with the location of child objects of the object you are going to place in a different thread.

          Somewhere you can find that object with their childs are moved to the thread. This is in new documentation. Since I do not know what and how it was in Qt 4, I think it may be no longer a problem as it was possibly in Qt 4. Again I have the fuzzy feeling some statements of Maya's blog may be outdated because of change to Qt5. However, that is a lot of crystal ball reading from somebody with a huge lack of experience in the threading area.

          May be someone as @mcosta or others understand this senstence and give a proper answer.

          Vote the answer(s) that helped you to solve your issue(s)

          1 Reply Last reply
          0
          • D Offline
            D Offline
            deleted28
            wrote on last edited by
            #5

            OK, thnak you

            1 Reply Last reply
            0
            • D deleted28

              Hello,
              i tried to get an answer from Maya but maybe my question is too stupid :)
              I do not really understand this sentence from

              By the way, one extremely important thing to note here is that you should NEVER allocate heap objects (using new) in the constructor of the QObject class as this allocation is then performed on the main thread and not on the new QThread instance, meaning that the newly created object is then owned by the main thread and not the QThread instance. 
              

              Link: http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/

              If i create a new default qt application using the wizzard I get the Mainwindow constructor, the other constructor I have is the WORKERS constructor.

              MainWindow::MainWindow(QWidget *parent) :
                  QMainWindow(parent),
                  ui(new Ui::MainWindow)
              {
                  ui->setupUi(this);
              
                  QThread* thread = new QThread;
                  Worker* worker = new Worker();
                  worker->moveToThread(thread);
              ...
              

              Where exactly i NEVER should create the Thread and Worker instance ?
              Can do as in the MainWindow constructor above (in this simple code it works).
              Maybe someone has a complete little project how to do and how NEVER do.
              thx

              JKSHJ Offline
              JKSHJ Offline
              JKSH
              Moderators
              wrote on last edited by
              #6

              Hi,

              @wally123 said:

              Where exactly i NEVER should create the Thread and Worker instance ?

              I wouldn't say "NEVER". The reason for that sentence is better explained in the QObject documentation (please read carefully the whole section about "Thread Affinity"):

              Note: A QObject's member variables do not automatically become its children. The parent-child relationship must be set by either passing a pointer to the child's constructor, or by calling setParent(). Without this step, the object's member variables will remain in the old thread when moveToThread() is called.

              Maya warned users not to create QObjects inside the Worker's constructor, because those QObjects would live in the original thread. However, if you set the parents correctly, all those QObjects would move to your new thread when you call worker->moveToThread(thread)

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

              1 Reply Last reply
              1
              • A Offline
                A Offline
                Asperamanca
                wrote on last edited by
                #7

                One simple alternative would be NOT to create any object in the constructor of the worker object, but instead create them inside an "init" slot which is called after the moveToThread.

                1 Reply Last reply
                0
                • D Offline
                  D Offline
                  deleted28
                  wrote on last edited by
                  #8

                  Thanks for your efforts to explain, but i do not get it yet.
                  Reading the entire docs confuse me even more.

                  The QThread Docs (5.5) example uses:

                  class WorkerThread : public QThread
                  

                  Question: Is this the sub-classing Maya mentioned in critic on Qt Docs ?

                  "This should immediately show why the recommended way of using QThreads in the documentation, namely to sub-class it and implement your own run() function, is very wrong. (Maya) "

                  Below i pasted a simple working code:

                  1.) Is the following code correct or is this something NEVER to do ?
                  2.) If this code is correct, how a "NEVER to do" but working code looks like ?
                  (how to create a worker instance in the worker constructor ?)
                  3.) If this code is correct, where is the associated correct parent setting ?

                  //worker.h
                  class Worker : public QObject
                  {
                      Q_OBJECT
                  private:
                  public:
                      explicit Worker(QObject *parent = 0);
                  signals:
                      void finished();
                      void error(QString);
                  public slots:
                      void process();
                  };
                  
                  // worker.cpp
                  #include "worker.h"
                  Worker::Worker(QObject *parent) : QObject(parent)
                  {
                  
                  }
                  
                  void Worker::process()
                  {
                      for(int i=0; i<10;i++) {
                          qDebug() << this->thread()->objectName();
                      }
                      emit finished();
                  }
                  
                  //mainwindow.cpp
                  MainWindow::MainWindow(QWidget *parent) :
                      QMainWindow(parent),
                      ui(new Ui::MainWindow)
                  {
                      ui->setupUi(this);
                  
                      QThread* thr_A = new QThread;
                      thr_A->setObjectName("thr_A");
                  
                      Worker* worker_A = new Worker();
                      worker_A->moveToThread(thr_A);
                  
                      connect(thr_A, SIGNAL(started()), worker_A, SLOT(process()));
                      connect(thr_A, SIGNAL(finished()), thr_A, SLOT(deleteLater()));
                      connect(worker_A, SIGNAL(finished()), thr_A, SLOT(quit()));
                      connect(worker_A, SIGNAL(finished()), worker_A, SLOT(deleteLater()));
                      connect(worker_A, SIGNAL(error(QString)), this, SLOT(errorString(QString)));
                  
                      thr_A->start(   );
                  }
                  
                  void MainWindow::errorString(QString _err)
                  {
                      qDebug("Error");
                  }
                  

                  thanks for patience :)

                  JKSHJ 1 Reply Last reply
                  0
                  • D deleted28

                    Thanks for your efforts to explain, but i do not get it yet.
                    Reading the entire docs confuse me even more.

                    The QThread Docs (5.5) example uses:

                    class WorkerThread : public QThread
                    

                    Question: Is this the sub-classing Maya mentioned in critic on Qt Docs ?

                    "This should immediately show why the recommended way of using QThreads in the documentation, namely to sub-class it and implement your own run() function, is very wrong. (Maya) "

                    Below i pasted a simple working code:

                    1.) Is the following code correct or is this something NEVER to do ?
                    2.) If this code is correct, how a "NEVER to do" but working code looks like ?
                    (how to create a worker instance in the worker constructor ?)
                    3.) If this code is correct, where is the associated correct parent setting ?

                    //worker.h
                    class Worker : public QObject
                    {
                        Q_OBJECT
                    private:
                    public:
                        explicit Worker(QObject *parent = 0);
                    signals:
                        void finished();
                        void error(QString);
                    public slots:
                        void process();
                    };
                    
                    // worker.cpp
                    #include "worker.h"
                    Worker::Worker(QObject *parent) : QObject(parent)
                    {
                    
                    }
                    
                    void Worker::process()
                    {
                        for(int i=0; i<10;i++) {
                            qDebug() << this->thread()->objectName();
                        }
                        emit finished();
                    }
                    
                    //mainwindow.cpp
                    MainWindow::MainWindow(QWidget *parent) :
                        QMainWindow(parent),
                        ui(new Ui::MainWindow)
                    {
                        ui->setupUi(this);
                    
                        QThread* thr_A = new QThread;
                        thr_A->setObjectName("thr_A");
                    
                        Worker* worker_A = new Worker();
                        worker_A->moveToThread(thr_A);
                    
                        connect(thr_A, SIGNAL(started()), worker_A, SLOT(process()));
                        connect(thr_A, SIGNAL(finished()), thr_A, SLOT(deleteLater()));
                        connect(worker_A, SIGNAL(finished()), thr_A, SLOT(quit()));
                        connect(worker_A, SIGNAL(finished()), worker_A, SLOT(deleteLater()));
                        connect(worker_A, SIGNAL(error(QString)), this, SLOT(errorString(QString)));
                    
                        thr_A->start(   );
                    }
                    
                    void MainWindow::errorString(QString _err)
                    {
                        qDebug("Error");
                    }
                    

                    thanks for patience :)

                    JKSHJ Offline
                    JKSHJ Offline
                    JKSH
                    Moderators
                    wrote on last edited by JKSH
                    #9

                    @wally123 said:

                    class WorkerThread : public QThread
                    

                    Question: Is this the sub-classing Maya mentioned in critic on Qt Docs ?

                    Yes, that is the sub-classing method that Maya criticized.

                    Note: Maya's article is quite old, and it does not cover all use cases. The current QThread documentation is more complete. It says there are 2 ways to use QThread:

                    1. Use a Worker QObject
                    2. Subclass QThread

                    To choose the "correct" way, you should ask yourself: Do you want to use signals and slots to communicate between threads?

                    • If you answer "yes", use a Worker QObject.
                    • If you answer "no", subclass QThread (or don't use QThread at all: http://doc.qt.io/qt-5/threads-technologies.html)

                    "This should immediately show why the recommended way of using QThreads in the documentation, namely to sub-class it and implement your own run() function, is very wrong. (Maya) "

                    I disagree. Olivier Goffart disagrees too: http://woboq.com/blog/qthread-you-were-not-doing-so-wrong.html (Olivier is an expert who designed many core parts of Qt)

                    Below i pasted a simple working code:

                    1.) Is the following code correct or is this something NEVER to do ?

                    Your code is correct.

                    2.) If this code is correct, how a "NEVER to do" but working code looks like ?
                    (how to create a worker instance in the worker constructor ?)

                    There are many many ways to write bad code -- it's hard to show them all!

                    3.) If this code is correct, where is the associated correct parent setting ?

                    Your code does not require parenting, because your Worker object does not create any objects.

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

                    1 Reply Last reply
                    1
                    • D Offline
                      D Offline
                      deleted28
                      wrote on last edited by deleted28
                      #10

                      @JKSH
                      much clearer now, wish I'll understand the docs also some day :)

                      1 Reply Last reply
                      0

                      • Login

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