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. inherite from QThread, but donnot overrider virtual void run(), is this OK?
Forum Updated to NodeBB v4.3 + New Features

inherite from QThread, but donnot overrider virtual void run(), is this OK?

Scheduled Pinned Locked Moved Unsolved General and Desktop
33 Posts 5 Posters 4.2k Views 2 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.
  • O Offline
    O Offline
    opengpu
    wrote on last edited by opengpu
    #10
    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 &);
    };
    

    thanks, and i will use this.

    ///////////////////////////////////////////////////////////////////////////////////////////////
    is this OK?
    the 'doWork' is slow, and the emit 'operate' is very very frequently.
    so is it OK when the previous signal's 'doWork' is still not finished & the next (maybe more than one)'operate' is already emitted.

    KroMignonK 1 Reply Last reply
    0
    • O opengpu
      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 &);
      };
      

      thanks, and i will use this.

      ///////////////////////////////////////////////////////////////////////////////////////////////
      is this OK?
      the 'doWork' is slow, and the emit 'operate' is very very frequently.
      so is it OK when the previous signal's 'doWork' is still not finished & the next (maybe more than one)'operate' is already emitted.

      KroMignonK Offline
      KroMignonK Offline
      KroMignon
      wrote on last edited by KroMignon
      #11

      @opengpu said in inherite from QThread, but donnot overrider virtual void run(), is this OK?:

      so is it OK when the previous signal's 'doWork' is still not finished & the next (maybe more than one)'operate' is already emitted.

      The worker QThread implements a QEventQueue, when a new signal emitted from Controller, it will be stored in message queue. And when slot has been processed on Worker, next message will be extract from queue. And so on.

      More details can be found here: https://www.toptal.com/qt/qt-multithreading-c-plus-plus

      Messages will be processed in the order of reception in WorkerThread.

      I would to initialization of Thread and Worker like this:

      Worker *worker = new Worker; // no need to hold pointer to worker 
      QThread *workerThread = new QThread; // no need to hold pointer to worker thread
      
      connect(this, &Controller::operate, worker, Worker::doWork);
      connect(worker, &Worker::resultReady, this, &Controller::handleResults);
      
      // delete worker on controller end
      connect(this, &QObject::destroyed, worker, Worker::deleteLater, Qt::DirectConnection);
      
      // stop and delete worker thread on worker end
      connect(worker, &QObject::destroyed, workerThread, [](QObject *){
          quit();
          wait();
          deleteLater();
      }, Qt::DirectConnection);
      
      worker->moveToThread(workerThread);
      workerThread.start();
      

      It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

      kshegunovK 1 Reply Last reply
      1
      • KroMignonK KroMignon

        @opengpu said in inherite from QThread, but donnot overrider virtual void run(), is this OK?:

        so is it OK when the previous signal's 'doWork' is still not finished & the next (maybe more than one)'operate' is already emitted.

        The worker QThread implements a QEventQueue, when a new signal emitted from Controller, it will be stored in message queue. And when slot has been processed on Worker, next message will be extract from queue. And so on.

        More details can be found here: https://www.toptal.com/qt/qt-multithreading-c-plus-plus

        Messages will be processed in the order of reception in WorkerThread.

        I would to initialization of Thread and Worker like this:

        Worker *worker = new Worker; // no need to hold pointer to worker 
        QThread *workerThread = new QThread; // no need to hold pointer to worker thread
        
        connect(this, &Controller::operate, worker, Worker::doWork);
        connect(worker, &Worker::resultReady, this, &Controller::handleResults);
        
        // delete worker on controller end
        connect(this, &QObject::destroyed, worker, Worker::deleteLater, Qt::DirectConnection);
        
        // stop and delete worker thread on worker end
        connect(worker, &QObject::destroyed, workerThread, [](QObject *){
            quit();
            wait();
            deleteLater();
        }, Qt::DirectConnection);
        
        worker->moveToThread(workerThread);
        workerThread.start();
        
        kshegunovK Offline
        kshegunovK Offline
        kshegunov
        Moderators
        wrote on last edited by
        #12

        @KroMignon said in inherite from QThread, but donnot overrider virtual void run(), is this OK?:

        connect(this, &QObject::destroyed, worker, Worker::deleteLater, Qt::DirectConnection);
        

        This is a race condition - deleteLater is a slot and it's not thread-safe. Don't force the connection type.

        Read and abide by the Qt Code of Conduct

        KroMignonK 1 Reply Last reply
        4
        • O Offline
          O Offline
          opengpu
          wrote on last edited by opengpu
          #13

          i want to set a min time interval inside which the emit operate or the slot doWork should be INVALID and do nothing.
          before when overrider the virtual run(), that's easy to do.

          how about this situation while using this worker-method?

          eg. if doWork is implemented and until 1 min passed, the signal or slot should not emit or implemented in this 1 min. and the signal/slot doesnot be renmembered, just ignore them.

          kshegunovK 1 Reply Last reply
          0
          • O opengpu

            i want to set a min time interval inside which the emit operate or the slot doWork should be INVALID and do nothing.
            before when overrider the virtual run(), that's easy to do.

            how about this situation while using this worker-method?

            eg. if doWork is implemented and until 1 min passed, the signal or slot should not emit or implemented in this 1 min. and the signal/slot doesnot be renmembered, just ignore them.

            kshegunovK Offline
            kshegunovK Offline
            kshegunov
            Moderators
            wrote on last edited by
            #14

            Emit a deadline (QDeadlineTimer) along with the input data. In the slot check if the deadline has expired, and if so just return immediately.

            Read and abide by the Qt Code of Conduct

            1 Reply Last reply
            0
            • O Offline
              O Offline
              opengpu
              wrote on last edited by opengpu
              #15
              QElapsedTimer m_ElapsedTimer;
              
              if ( !m_ElapsedTimer.isValid() ||  m_ElapsedTimer.hasExpired(timeout))
              {
                  emit signalSendEmail();
                  m_ElapsedTimer.restart();
              }
              

              i want to write like this, this will not restrict the 1st time emit, and since the 1st emit, the next emit is only allowed outof timeout milliseconds.
              However, i want the exe runs very very long time. the qinit64 seems still not that long enough for the longest interval in theory(qint64 is only about 214783 seconds). What will happen if the real time interval is longer than this?
              And what is the best method to get the longest time interval supportted in code?

              jsulmJ kshegunovK 2 Replies Last reply
              0
              • O opengpu
                QElapsedTimer m_ElapsedTimer;
                
                if ( !m_ElapsedTimer.isValid() ||  m_ElapsedTimer.hasExpired(timeout))
                {
                    emit signalSendEmail();
                    m_ElapsedTimer.restart();
                }
                

                i want to write like this, this will not restrict the 1st time emit, and since the 1st emit, the next emit is only allowed outof timeout milliseconds.
                However, i want the exe runs very very long time. the qinit64 seems still not that long enough for the longest interval in theory(qint64 is only about 214783 seconds). What will happen if the real time interval is longer than this?
                And what is the best method to get the longest time interval supportted in code?

                jsulmJ Offline
                jsulmJ Offline
                jsulm
                Lifetime Qt Champion
                wrote on last edited by jsulm
                #16

                @opengpu See my answer in your other thread (https://forum.qt.io/topic/104026/about-the-longest-elapsed-time-in-qt). I really have no idea why you think it is 214783 seconds only when using qint64...

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

                O 1 Reply Last reply
                0
                • jsulmJ jsulm

                  @opengpu See my answer in your other thread (https://forum.qt.io/topic/104026/about-the-longest-elapsed-time-in-qt). I really have no idea why you think it is 214783 seconds only when using qint64...

                  O Offline
                  O Offline
                  opengpu
                  wrote on last edited by
                  #17

                  @jsulm thank you. i got it from INT_MAX, which is int32

                  jsulmJ 1 Reply Last reply
                  0
                  • O opengpu

                    @jsulm thank you. i got it from INT_MAX, which is int32

                    jsulmJ Offline
                    jsulmJ Offline
                    jsulm
                    Lifetime Qt Champion
                    wrote on last edited by jsulm
                    #18

                    @opengpu With int32 you have more than 2 million seconds, not 214783

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

                    1 Reply Last reply
                    0
                    • O Offline
                      O Offline
                      opengpu
                      wrote on last edited by
                      #19

                      @opengpu said in inherite from QThread, but donnot overrider virtual void run(), is this OK?:

                      workerThread

                      workerThread donot need sleep?

                      jsulmJ 1 Reply Last reply
                      0
                      • O opengpu

                        @opengpu said in inherite from QThread, but donnot overrider virtual void run(), is this OK?:

                        workerThread

                        workerThread donot need sleep?

                        jsulmJ Offline
                        jsulmJ Offline
                        jsulm
                        Lifetime Qt Champion
                        wrote on last edited by
                        #20

                        @opengpu said in inherite from QThread, but donnot overrider virtual void run(), is this OK?:

                        workerThread donot need sleep?

                        No, they are not humans :-)
                        Why are you asking? A thread can sleep or be busy.

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

                        O 1 Reply Last reply
                        1
                        • jsulmJ jsulm

                          @opengpu said in inherite from QThread, but donnot overrider virtual void run(), is this OK?:

                          workerThread donot need sleep?

                          No, they are not humans :-)
                          Why are you asking? A thread can sleep or be busy.

                          O Offline
                          O Offline
                          opengpu
                          wrote on last edited by
                          #21

                          @jsulm ok, so it will automatically sleep when no signal or event, right?
                          because i used to overider the virtual run()
                          thanks

                          jsulmJ 1 Reply Last reply
                          0
                          • kshegunovK kshegunov

                            @KroMignon said in inherite from QThread, but donnot overrider virtual void run(), is this OK?:

                            connect(this, &QObject::destroyed, worker, Worker::deleteLater, Qt::DirectConnection);
                            

                            This is a race condition - deleteLater is a slot and it's not thread-safe. Don't force the connection type.

                            KroMignonK Offline
                            KroMignonK Offline
                            KroMignon
                            wrote on last edited by KroMignon
                            #22

                            @kshegunov said in inherite from QThread, but donnot overrider virtual void run(), is this OK?:

                            This is a race condition - deleteLater is a slot and it's not thread-safe. Don't force the connection type.

                            Where did you found this information.... I mean not thread safe?
                            Because on Qt Mailing list, Thiago Macieira (which is deep involved in Qt devlopement) has written:

                            It's thread-safe with almost any operation, except one: the actual object's
                            deletion, of course.

                            But we haven't documented it as such. It just happens to be due to the
                            implementation.

                            ==> cf. https://lists.qt-project.org/pipermail/interest/2015-October/019197.html

                            It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                            kshegunovK 1 Reply Last reply
                            0
                            • O opengpu

                              @jsulm ok, so it will automatically sleep when no signal or event, right?
                              because i used to overider the virtual run()
                              thanks

                              jsulmJ Offline
                              jsulmJ Offline
                              jsulm
                              Lifetime Qt Champion
                              wrote on last edited by
                              #23

                              @opengpu If you call exec() in your run() method then your thread will have an event loop and sleep if there is nothing to do. Else it will finish as soon as run() finishes (https://doc.qt.io/qt-5/qthread.html#run).

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

                              O 1 Reply Last reply
                              1
                              • jsulmJ jsulm

                                @opengpu If you call exec() in your run() method then your thread will have an event loop and sleep if there is nothing to do. Else it will finish as soon as run() finishes (https://doc.qt.io/qt-5/qthread.html#run).

                                O Offline
                                O Offline
                                opengpu
                                wrote on last edited by
                                #24

                                @jsulm i used to not call exec, and use my own loop, so it need sleep, lol

                                1 Reply Last reply
                                0
                                • KroMignonK KroMignon

                                  @kshegunov said in inherite from QThread, but donnot overrider virtual void run(), is this OK?:

                                  This is a race condition - deleteLater is a slot and it's not thread-safe. Don't force the connection type.

                                  Where did you found this information.... I mean not thread safe?
                                  Because on Qt Mailing list, Thiago Macieira (which is deep involved in Qt devlopement) has written:

                                  It's thread-safe with almost any operation, except one: the actual object's
                                  deletion, of course.

                                  But we haven't documented it as such. It just happens to be due to the
                                  implementation.

                                  ==> cf. https://lists.qt-project.org/pipermail/interest/2015-October/019197.html

                                  kshegunovK Offline
                                  kshegunovK Offline
                                  kshegunov
                                  Moderators
                                  wrote on last edited by
                                  #25

                                  @KroMignon said in inherite from QThread, but donnot overrider virtual void run(), is this OK?:

                                  Where did you found this information.... I mean not thread safe?

                                  Documentation. There's no promise Qt made about it being thread safe, and as Thiago noted this is an implementation detail you're relying on. It may change in Qt6 (it may even change in Qt5) and then you're going to wonder why a nasty bug suddenly appeared in your codebase.

                                  Read and abide by the Qt Code of Conduct

                                  KroMignonK 1 Reply Last reply
                                  3
                                  • O opengpu
                                    QElapsedTimer m_ElapsedTimer;
                                    
                                    if ( !m_ElapsedTimer.isValid() ||  m_ElapsedTimer.hasExpired(timeout))
                                    {
                                        emit signalSendEmail();
                                        m_ElapsedTimer.restart();
                                    }
                                    

                                    i want to write like this, this will not restrict the 1st time emit, and since the 1st emit, the next emit is only allowed outof timeout milliseconds.
                                    However, i want the exe runs very very long time. the qinit64 seems still not that long enough for the longest interval in theory(qint64 is only about 214783 seconds). What will happen if the real time interval is longer than this?
                                    And what is the best method to get the longest time interval supportted in code?

                                    kshegunovK Offline
                                    kshegunovK Offline
                                    kshegunov
                                    Moderators
                                    wrote on last edited by
                                    #26

                                    @opengpu said in inherite from QThread, but donnot overrider virtual void run(), is this OK?:

                                    QElapsedTimer m_ElapsedTimer;
                                    
                                    if ( !m_ElapsedTimer.isValid() ||  m_ElapsedTimer.hasExpired(timeout))
                                    {
                                        emit signalSendEmail();
                                        m_ElapsedTimer.restart();
                                    }
                                    

                                    i want to write like this, this will not restrict the 1st time emit, and since the 1st emit, the next emit is only allowed outof timeout milliseconds.
                                    However, i want the exe runs very very long time. the qinit64 seems still not that long enough for the longest interval in theory(qint64 is only about 214783 seconds). What will happen if the real time interval is longer than this?
                                    And what is the best method to get the longest time interval supportted in code?

                                    // first emit
                                    emit signalSendEmail(QDeadlineTimer(QDeadlineTimer::Forever));
                                    
                                    // More emits
                                    // ...
                                    emit signalSendEmail(QDeadlineTimer::current() + 1000 * 3600); // 3600s = 1 hour
                                    

                                    In the slot it's as easy to check as:

                                    void Class::slotThatSendsEmails(const QDeadlineTimer & deadline)
                                    {
                                        if (deadline.hasExpired())
                                            return;
                                    
                                        // Code that matters
                                    }
                                    

                                    Read and abide by the Qt Code of Conduct

                                    O 1 Reply Last reply
                                    1
                                    • kshegunovK kshegunov

                                      @KroMignon said in inherite from QThread, but donnot overrider virtual void run(), is this OK?:

                                      Where did you found this information.... I mean not thread safe?

                                      Documentation. There's no promise Qt made about it being thread safe, and as Thiago noted this is an implementation detail you're relying on. It may change in Qt6 (it may even change in Qt5) and then you're going to wonder why a nasty bug suddenly appeared in your codebase.

                                      KroMignonK Offline
                                      KroMignonK Offline
                                      KroMignon
                                      wrote on last edited by
                                      #27

                                      @kshegunov said in inherite from QThread, but donnot overrider virtual void run(), is this OK?:

                                      Documentation

                                      Sorry, I don't want to be boring, I are certainly right...
                                      But it would be nice if you can give me a pointer of your affirmation...
                                      I am following Qt Forum to learn. You say I will have trouble doing this, but not really any information else...

                                      It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                                      jsulmJ kshegunovK 2 Replies Last reply
                                      0
                                      • KroMignonK KroMignon

                                        @kshegunov said in inherite from QThread, but donnot overrider virtual void run(), is this OK?:

                                        Documentation

                                        Sorry, I don't want to be boring, I are certainly right...
                                        But it would be nice if you can give me a pointer of your affirmation...
                                        I am following Qt Forum to learn. You say I will have trouble doing this, but not really any information else...

                                        jsulmJ Offline
                                        jsulmJ Offline
                                        jsulm
                                        Lifetime Qt Champion
                                        wrote on last edited by
                                        #28

                                        @KroMignon In documentation it is usually stated that a method is thread-safe (if it is), see for example bool QObject::disconnect
                                        If there is no mention of thread-safety then you should assume it is not.

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

                                        1 Reply Last reply
                                        1
                                        • kshegunovK kshegunov

                                          @opengpu said in inherite from QThread, but donnot overrider virtual void run(), is this OK?:

                                          QElapsedTimer m_ElapsedTimer;
                                          
                                          if ( !m_ElapsedTimer.isValid() ||  m_ElapsedTimer.hasExpired(timeout))
                                          {
                                              emit signalSendEmail();
                                              m_ElapsedTimer.restart();
                                          }
                                          

                                          i want to write like this, this will not restrict the 1st time emit, and since the 1st emit, the next emit is only allowed outof timeout milliseconds.
                                          However, i want the exe runs very very long time. the qinit64 seems still not that long enough for the longest interval in theory(qint64 is only about 214783 seconds). What will happen if the real time interval is longer than this?
                                          And what is the best method to get the longest time interval supportted in code?

                                          // first emit
                                          emit signalSendEmail(QDeadlineTimer(QDeadlineTimer::Forever));
                                          
                                          // More emits
                                          // ...
                                          emit signalSendEmail(QDeadlineTimer::current() + 1000 * 3600); // 3600s = 1 hour
                                          

                                          In the slot it's as easy to check as:

                                          void Class::slotThatSendsEmails(const QDeadlineTimer & deadline)
                                          {
                                              if (deadline.hasExpired())
                                                  return;
                                          
                                              // Code that matters
                                          }
                                          
                                          O Offline
                                          O Offline
                                          opengpu
                                          wrote on last edited by
                                          #29

                                          @kshegunov said in inherite from QThread, but donnot overrider virtual void run(), is this OK?:

                                          QDeadlineTimer

                                          thank you, but why did you persist on using QDeadlineTimer?
                                          donot emit the signal isn't better?
                                          eg. watch on the stock price, as the price is changing very frequently, so i set this min-interval to forbid the alert too frequently(at most 1 time 1 interval-time).
                                          that's my method, and i donnot is QDeadlineTimer better? or my code above has some bug...

                                          kshegunovK 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