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. How do QThread::start and Worker::doWork related?
Forum Updated to NodeBB v4.3 + New Features

How do QThread::start and Worker::doWork related?

Scheduled Pinned Locked Moved Solved General and Desktop
21 Posts 8 Posters 8.3k Views 3 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.
  • J Offline
    J Offline
    jronald
    wrote on 9 May 2017, 17:19 last edited by kshegunov 5 Nov 2017, 09:08
    #1

    From the doc of QThread:

      class Worker : public QObject
      {
          Q_OBJECT
    
      public slots:
          void doWork(const QString &parameter) {
              QString result;
              /* ... here is the expensive or blocking operation ... */
              emit resultReady(result);
          }
    
      signals:
          void resultReady(const QString &result);
      };
    
      class Controller : public QObject
      {
          Q_OBJECT
          QThread workerThread;
      public:
          Controller() {
              Worker *worker = new Worker;
              worker->moveToThread(&workerThread);
              connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
              connect(this, &Controller::operate, worker, &Worker::doWork);
              connect(worker, &Worker::resultReady, this, &Controller::handleResults);
              workerThread.start();
          }
          ~Controller() {
              workerThread.quit();
              workerThread.wait();
          }
      public slots:
          void handleResults(const QString &);
      signals:
          void operate(const QString &);
      };
    

    Question:
    How do

    workerThread::start
    

    and

    Worker::doWork
    

    related?
    Thanks in advance.

    [Please don't delete your topics. Restored. ~kshegunov]

    J 1 Reply Last reply 10 May 2017, 05:10
    0
    • D Offline
      D Offline
      dheerendra
      Qt Champions 2022
      wrote on 9 May 2017, 17:48 last edited by
      #2

      Whenever u start thread it will execute slot dowork.

      Dheerendra
      @Community Service
      Certified Qt Specialist
      http://www.pthinks.com

      1 Reply Last reply
      0
      • B Offline
        B Offline
        beecksche
        wrote on 9 May 2017, 18:16 last edited by beecksche 5 Sept 2017, 18:21
        #3

        Hi @jronald
        The start function just starts the event loop (afaik).
        The slot doWork of the Worker class is connected to the signal operate of the controller

        connect(this, &Controller::operate, worker, &Worker::doWork);
        

        So if you emit the operate signal the doWork slot will be executed in the started thread.

        If you subclass QThread and override the run function, it will be executed in another thread by calling the start function:

        class WorkerThread : public QThread
        {
            Q_OBJECT
            void run() Q_DECL_OVERRIDE {
                QString result;
                /* ... here is the expensive or blocking operation ... */
                emit resultReady(result);
            }
        signals:
            void resultReady(const QString &s);
        };
        
        void MyObject::startWorkInAThread()
        {
            WorkerThread *workerThread = new WorkerThread(this);
            connect(workerThread, &WorkerThread::resultReady, this, &MyObject::handleResults);
            connect(workerThread, &WorkerThread::finished, workerThread, &QObject::deleteLater);
            workerThread->start();
        }
        
        J 1 Reply Last reply 10 May 2017, 02:15
        3
        • B beecksche
          9 May 2017, 18:16

          Hi @jronald
          The start function just starts the event loop (afaik).
          The slot doWork of the Worker class is connected to the signal operate of the controller

          connect(this, &Controller::operate, worker, &Worker::doWork);
          

          So if you emit the operate signal the doWork slot will be executed in the started thread.

          If you subclass QThread and override the run function, it will be executed in another thread by calling the start function:

          class WorkerThread : public QThread
          {
              Q_OBJECT
              void run() Q_DECL_OVERRIDE {
                  QString result;
                  /* ... here is the expensive or blocking operation ... */
                  emit resultReady(result);
              }
          signals:
              void resultReady(const QString &s);
          };
          
          void MyObject::startWorkInAThread()
          {
              WorkerThread *workerThread = new WorkerThread(this);
              connect(workerThread, &WorkerThread::resultReady, this, &MyObject::handleResults);
              connect(workerThread, &WorkerThread::finished, workerThread, &QObject::deleteLater);
              workerThread->start();
          }
          
          J Offline
          J Offline
          jronald
          wrote on 10 May 2017, 02:15 last edited by
          #4

          @beecksche said in How do QThread::start and Worker::doWork related?:

          The slot doWork of the Worker class is connected to the signal operate of the controller

          connect(this, &Controller::operate, worker, &Worker::doWork);
          

          Who emits the Controller::operate signal?
          I've checked doc of QThread, but no answer.

          J F 2 Replies Last reply 10 May 2017, 04:39
          0
          • J jronald
            10 May 2017, 02:15

            @beecksche said in How do QThread::start and Worker::doWork related?:

            The slot doWork of the Worker class is connected to the signal operate of the controller

            connect(this, &Controller::operate, worker, &Worker::doWork);
            

            Who emits the Controller::operate signal?
            I've checked doc of QThread, but no answer.

            J Offline
            J Offline
            jsulm
            Lifetime Qt Champion
            wrote on 10 May 2017, 04:39 last edited by VRonin 5 Oct 2017, 06:52
            #5

            @jronald said in How do QThread::start and Worker::doWork related?:

            Who emits the Controller::operate signal?

            It's just an example. Who emits the signal is not of interest in this example. It just shows how you can connect the worker with the controller.
            In a real application the controller would emit this signal whenever the action needs to be executed in the thread.

            https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            3
            • J jronald
              10 May 2017, 02:15

              @beecksche said in How do QThread::start and Worker::doWork related?:

              The slot doWork of the Worker class is connected to the signal operate of the controller

              connect(this, &Controller::operate, worker, &Worker::doWork);
              

              Who emits the Controller::operate signal?
              I've checked doc of QThread, but no answer.

              F Offline
              F Offline
              Flotisable
              wrote on 10 May 2017, 04:41 last edited by
              #6

              @jronald
              the document does not say who emit the Controller::operate signal.

              it just gives you a way to start doWork by emit Controller::operate signal, as for where or when you want to emit the signal, it depends on how you define the Controller

              for example, you can add a public member function in Controller

              doWork() { emit operate; }
              

              then when you call doWork in your main function, it will start Worker::doWork in another thread.

              1 Reply Last reply
              2
              • J jronald
                9 May 2017, 17:19

                From the doc of QThread:

                  class Worker : public QObject
                  {
                      Q_OBJECT
                
                  public slots:
                      void doWork(const QString &parameter) {
                          QString result;
                          /* ... here is the expensive or blocking operation ... */
                          emit resultReady(result);
                      }
                
                  signals:
                      void resultReady(const QString &result);
                  };
                
                  class Controller : public QObject
                  {
                      Q_OBJECT
                      QThread workerThread;
                  public:
                      Controller() {
                          Worker *worker = new Worker;
                          worker->moveToThread(&workerThread);
                          connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
                          connect(this, &Controller::operate, worker, &Worker::doWork);
                          connect(worker, &Worker::resultReady, this, &Controller::handleResults);
                          workerThread.start();
                      }
                      ~Controller() {
                          workerThread.quit();
                          workerThread.wait();
                      }
                  public slots:
                      void handleResults(const QString &);
                  signals:
                      void operate(const QString &);
                  };
                

                Question:
                How do

                workerThread::start
                

                and

                Worker::doWork
                

                related?
                Thanks in advance.

                [Please don't delete your topics. Restored. ~kshegunov]

                J Offline
                J Offline
                J.Hilk
                Moderators
                wrote on 10 May 2017, 05:10 last edited by
                #7

                @jronald if you want to start the doWork slot immediately after starting the thread, you can link those two together

                   Controller() {
                       Worker *worker = new Worker;
                       worker->moveToThread(&workerThread);
                       connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
                       connect(this, &Controller::operate, worker, &Worker::doWork);
                       connect(worker, &Worker::resultReady, this, &Controller::handleResults);
                
                       connect(&workerThread, &QThread::started, this, &Controller::operate); //<-- Added connection
                
                       workerThread.start();
                   }
                

                Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                Q: What's that?
                A: It's blue light.
                Q: What does it do?
                A: It turns blue.

                J 1 Reply Last reply 10 May 2017, 06:41
                2
                • J J.Hilk
                  10 May 2017, 05:10

                  @jronald if you want to start the doWork slot immediately after starting the thread, you can link those two together

                     Controller() {
                         Worker *worker = new Worker;
                         worker->moveToThread(&workerThread);
                         connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
                         connect(this, &Controller::operate, worker, &Worker::doWork);
                         connect(worker, &Worker::resultReady, this, &Controller::handleResults);
                  
                         connect(&workerThread, &QThread::started, this, &Controller::operate); //<-- Added connection
                  
                         workerThread.start();
                     }
                  
                  J Offline
                  J Offline
                  jronald
                  wrote on 10 May 2017, 06:41 last edited by
                  #8

                  @J.Hilk OK. It seems that even a running thread could be moved from thread to thread, is it true?

                  VRoninV J 2 Replies Last reply 10 May 2017, 06:54
                  0
                  • J jronald
                    10 May 2017, 06:41

                    @J.Hilk OK. It seems that even a running thread could be moved from thread to thread, is it true?

                    VRoninV Offline
                    VRoninV Offline
                    VRonin
                    wrote on 10 May 2017, 06:54 last edited by
                    #9

                    @jronald QThread is not the thread itself. it's a wrapper around it. I still don't see the point in moving a QThread object to another thread

                    "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                    ~Napoleon Bonaparte

                    On a crusade to banish setIndexWidget() from the holy land of Qt

                    1 Reply Last reply
                    3
                    • J jronald
                      10 May 2017, 06:41

                      @J.Hilk OK. It seems that even a running thread could be moved from thread to thread, is it true?

                      J Offline
                      J Offline
                      J.Hilk
                      Moderators
                      wrote on 10 May 2017, 07:05 last edited by
                      #10

                      @jronald said in How do QThread::start and Worker::doWork related?:

                      @J.Hilk OK. It seems that even a running thread could be moved from thread to thread, is it true?

                      The QThread object itself just manages one thread. That said, it's not strictly necessary to move/asign your worker-object to the QThread-Object before it is started.

                      But if you create for example a QTimer in your worker and move it than later to an other QThread, that won't work. Iirc the Timer releated things are ignored/not executed.

                      That is also true if you create instances of classes that have internal time specific things.
                      For example I run into this, when I had an QSerialPort object that was created in the constructor, had to move it the an initialization function that was called after the QThread started.


                      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                      Q: What's that?
                      A: It's blue light.
                      Q: What does it do?
                      A: It turns blue.

                      kshegunovK J 2 Replies Last reply 10 May 2017, 18:45
                      0
                      • J J.Hilk
                        10 May 2017, 07:05

                        @jronald said in How do QThread::start and Worker::doWork related?:

                        @J.Hilk OK. It seems that even a running thread could be moved from thread to thread, is it true?

                        The QThread object itself just manages one thread. That said, it's not strictly necessary to move/asign your worker-object to the QThread-Object before it is started.

                        But if you create for example a QTimer in your worker and move it than later to an other QThread, that won't work. Iirc the Timer releated things are ignored/not executed.

                        That is also true if you create instances of classes that have internal time specific things.
                        For example I run into this, when I had an QSerialPort object that was created in the constructor, had to move it the an initialization function that was called after the QThread started.

                        kshegunovK Offline
                        kshegunovK Offline
                        kshegunov
                        Moderators
                        wrote on 10 May 2017, 18:45 last edited by
                        #11

                        @J.Hilk said in How do QThread::start and Worker::doWork related?:

                        But if you create for example a QTimer in your worker and move it than later to an other QThread, that won't work. Iirc the Timer releated things are ignored/not executed.

                        The timer should be stopped before moving to another thread, you can't move an active timer.

                        Read and abide by the Qt Code of Conduct

                        1 Reply Last reply
                        2
                        • J J.Hilk
                          10 May 2017, 07:05

                          @jronald said in How do QThread::start and Worker::doWork related?:

                          @J.Hilk OK. It seems that even a running thread could be moved from thread to thread, is it true?

                          The QThread object itself just manages one thread. That said, it's not strictly necessary to move/asign your worker-object to the QThread-Object before it is started.

                          But if you create for example a QTimer in your worker and move it than later to an other QThread, that won't work. Iirc the Timer releated things are ignored/not executed.

                          That is also true if you create instances of classes that have internal time specific things.
                          For example I run into this, when I had an QSerialPort object that was created in the constructor, had to move it the an initialization function that was called after the QThread started.

                          J Offline
                          J Offline
                          jronald
                          wrote on 11 May 2017, 08:57 last edited by
                          #12

                          @J.Hilk @VRonin @kshegunov
                          Not clear, I think I'll try the native API. Thanks.

                          VRoninV kshegunovK 2 Replies Last reply 11 May 2017, 09:07
                          0
                          • J jronald
                            11 May 2017, 08:57

                            @J.Hilk @VRonin @kshegunov
                            Not clear, I think I'll try the native API. Thanks.

                            VRoninV Offline
                            VRoninV Offline
                            VRonin
                            wrote on 11 May 2017, 09:07 last edited by
                            #13

                            @jronald said in How do QThread::start and Worker::doWork related?:

                            Not clear

                            Try taking a look at https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/

                            "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                            ~Napoleon Bonaparte

                            On a crusade to banish setIndexWidget() from the holy land of Qt

                            J 1 Reply Last reply 11 May 2017, 16:55
                            2
                            • J jronald
                              11 May 2017, 08:57

                              @J.Hilk @VRonin @kshegunov
                              Not clear, I think I'll try the native API. Thanks.

                              kshegunovK Offline
                              kshegunovK Offline
                              kshegunov
                              Moderators
                              wrote on 11 May 2017, 09:12 last edited by
                              #14

                              @jronald said in How do QThread::start and Worker::doWork related?:

                              Not clear, I think I'll try the native API.

                              What isn't clear exactly?

                              Read and abide by the Qt Code of Conduct

                              J 1 Reply Last reply 11 May 2017, 17:00
                              0
                              • VRoninV VRonin
                                11 May 2017, 09:07

                                @jronald said in How do QThread::start and Worker::doWork related?:

                                Not clear

                                Try taking a look at https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/

                                J Offline
                                J Offline
                                jronald
                                wrote on 11 May 2017, 16:55 last edited by
                                #15

                                @VRonin Thanks, though I've almost complete my project in a native way, I'll learn Qt to see if it is excellent.

                                1 Reply Last reply
                                0
                                • kshegunovK kshegunov
                                  11 May 2017, 09:12

                                  @jronald said in How do QThread::start and Worker::doWork related?:

                                  Not clear, I think I'll try the native API.

                                  What isn't clear exactly?

                                  J Offline
                                  J Offline
                                  jronald
                                  wrote on 11 May 2017, 17:00 last edited by
                                  #16

                                  @kshegunov

                                  @kshegunov said in How do QThread::start and Worker::doWork related?:

                                  @jronald said in How do QThread::start and Worker::doWork related?:

                                  Not clear, I think I'll try the native API.

                                  What isn't clear exactly?

                                  Some questions can't be answered, for example:

                                  1. what if many workers move to the same thread object
                                  2. worker and QThread object are decoupled, what is the mechanism to keep both valid when working? By something like share_ptr?
                                  B kshegunovK 2 Replies Last reply 11 May 2017, 18:04
                                  0
                                  • J jronald
                                    11 May 2017, 17:00

                                    @kshegunov

                                    @kshegunov said in How do QThread::start and Worker::doWork related?:

                                    @jronald said in How do QThread::start and Worker::doWork related?:

                                    Not clear, I think I'll try the native API.

                                    What isn't clear exactly?

                                    Some questions can't be answered, for example:

                                    1. what if many workers move to the same thread object
                                    2. worker and QThread object are decoupled, what is the mechanism to keep both valid when working? By something like share_ptr?
                                    B Offline
                                    B Offline
                                    beecksche
                                    wrote on 11 May 2017, 18:04 last edited by beecksche 5 Nov 2017, 18:37
                                    #17

                                    @jronald
                                    I hope i understand your questions correctly.

                                    By calling the QThread::start a new event loop is started. The objects moved to this QThread will be executed in that event loop. So if multiple objects are moved to the thread the operations are done in sequence.

                                    To communicate between the objects moved to the thread and object in another thread you can use the signal/slot mechanism with queued connections.

                                    Here a also useful informations: http://doc.qt.io/qt-5.8/threads-synchronizing.html and http://doc.qt.io/qt-5/threads-technologies.html

                                    J 1 Reply Last reply 12 May 2017, 08:41
                                    2
                                    • B beecksche
                                      11 May 2017, 18:04

                                      @jronald
                                      I hope i understand your questions correctly.

                                      By calling the QThread::start a new event loop is started. The objects moved to this QThread will be executed in that event loop. So if multiple objects are moved to the thread the operations are done in sequence.

                                      To communicate between the objects moved to the thread and object in another thread you can use the signal/slot mechanism with queued connections.

                                      Here a also useful informations: http://doc.qt.io/qt-5.8/threads-synchronizing.html and http://doc.qt.io/qt-5/threads-technologies.html

                                      J Offline
                                      J Offline
                                      jronald
                                      wrote on 12 May 2017, 08:41 last edited by jronald 5 Dec 2017, 09:03
                                      #18

                                      @beecksche The mechanism is general and robust, the trade off between runtime efficiency and develop efficiency while retaining the profession of C/C++ is very good.

                                      1 Reply Last reply
                                      0
                                      • J jronald
                                        11 May 2017, 17:00

                                        @kshegunov

                                        @kshegunov said in How do QThread::start and Worker::doWork related?:

                                        @jronald said in How do QThread::start and Worker::doWork related?:

                                        Not clear, I think I'll try the native API.

                                        What isn't clear exactly?

                                        Some questions can't be answered, for example:

                                        1. what if many workers move to the same thread object
                                        2. worker and QThread object are decoupled, what is the mechanism to keep both valid when working? By something like share_ptr?
                                        kshegunovK Offline
                                        kshegunovK Offline
                                        kshegunov
                                        Moderators
                                        wrote on 12 May 2017, 15:34 last edited by
                                        #19

                                        @jronald said in How do QThread::start and Worker::doWork related?:

                                        what if many workers move to the same thread object

                                        The QObject::moveToThread method is not thread-safe. In consequence the object can be moved only from one thread and it is the one it exists in (see thread affinity). Aside from this there's no limit on how many worker objects can be moved into a thread. All the slot invocations across threads are queued (by default) in the thread's event queue and are dispatched to the relevant objects in sequence.

                                        worker and QThread object are decoupled, what is the mechanism to keep both valid when working? By something like share_ptr?

                                        That's up to you. I just connect all the needed signals and don't keep reference to either object, or I create them in the stack and leave the stack unwinding to take care of the objects' destruction. E.g:

                                        QThread * thread = new QThread();
                                        thread->start();
                                        
                                        QObject * worker = new QObject(); // Or whatever type your worker is.
                                        worker->moveToThread(thread);
                                        
                                        // Connect worker and thread and w/e else is needed to be connected
                                        QObject::connect(thread, &QThread::finished, worker, &QObject::deleteLater); // Takes care to delete the worker whenever the thread's quitting
                                        
                                        // Do unrelated stuff ... ...
                                        
                                        // Tell the thread to quit, wait for it and continue on
                                        thread->quit();
                                        thread->wait();
                                        

                                        As QThread is already a QObject you can have it parented which means the parent will auto-delete the children whenever it is deleted itself.

                                        Read and abide by the Qt Code of Conduct

                                        J 1 Reply Last reply 12 May 2017, 17:40
                                        2
                                        • kshegunovK kshegunov
                                          12 May 2017, 15:34

                                          @jronald said in How do QThread::start and Worker::doWork related?:

                                          what if many workers move to the same thread object

                                          The QObject::moveToThread method is not thread-safe. In consequence the object can be moved only from one thread and it is the one it exists in (see thread affinity). Aside from this there's no limit on how many worker objects can be moved into a thread. All the slot invocations across threads are queued (by default) in the thread's event queue and are dispatched to the relevant objects in sequence.

                                          worker and QThread object are decoupled, what is the mechanism to keep both valid when working? By something like share_ptr?

                                          That's up to you. I just connect all the needed signals and don't keep reference to either object, or I create them in the stack and leave the stack unwinding to take care of the objects' destruction. E.g:

                                          QThread * thread = new QThread();
                                          thread->start();
                                          
                                          QObject * worker = new QObject(); // Or whatever type your worker is.
                                          worker->moveToThread(thread);
                                          
                                          // Connect worker and thread and w/e else is needed to be connected
                                          QObject::connect(thread, &QThread::finished, worker, &QObject::deleteLater); // Takes care to delete the worker whenever the thread's quitting
                                          
                                          // Do unrelated stuff ... ...
                                          
                                          // Tell the thread to quit, wait for it and continue on
                                          thread->quit();
                                          thread->wait();
                                          

                                          As QThread is already a QObject you can have it parented which means the parent will auto-delete the children whenever it is deleted itself.

                                          J Offline
                                          J Offline
                                          jronald
                                          wrote on 12 May 2017, 17:40 last edited by jronald 5 Dec 2017, 17:41
                                          #20

                                          @kshegunov The signal & slot mechanism just takes thread selection into consideration, others still keep simple, right? I think it's quite good.

                                          kshegunovK 1 Reply Last reply 13 May 2017, 15:04
                                          0

                                          2/21

                                          9 May 2017, 17:48

                                          topic:navigator.unread, 19
                                          • Login

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