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. If the execution time of slot function is greater than the interval of qtimer?
Forum Updated to NodeBB v4.3 + New Features

If the execution time of slot function is greater than the interval of qtimer?

Scheduled Pinned Locked Moved Solved General and Desktop
18 Posts 7 Posters 2.4k 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.
  • LimerL Offline
    LimerL Offline
    Limer
    wrote on last edited by
    #1
    slots:
        /* if it will need 1000ms to finish */
        void doBusyThings()
        {
            ...
            ...
        }
    
    QTimer* timer = new QTimer(this);
    connect(timer, SIGNAL(tiermOut()), this, SLOT(doBusyThings()));
    timer->start(500);
    

    What happens to doBusyThings()?

    I mean doBusyThings() will be pushed into a queue and wait to execute? Or kill the running doBusyThings() and continue to execute the next?

    J.HilkJ aha_1980A 2 Replies Last reply
    1
    • LimerL Limer
      slots:
          /* if it will need 1000ms to finish */
          void doBusyThings()
          {
              ...
              ...
          }
      
      QTimer* timer = new QTimer(this);
      connect(timer, SIGNAL(tiermOut()), this, SLOT(doBusyThings()));
      timer->start(500);
      

      What happens to doBusyThings()?

      I mean doBusyThings() will be pushed into a queue and wait to execute? Or kill the running doBusyThings() and continue to execute the next?

      J.HilkJ Offline
      J.HilkJ Offline
      J.Hilk
      Moderators
      wrote on last edited by J.Hilk
      #2

      @Limer
      that depends, do you do sketchy stuff in busyThings, like start a QEventLoop or call ProcessEvents ?

      If not, than the timeout events are queued and executed the next eventloop cycle.


      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.

      1 Reply Last reply
      4
      • LimerL Limer
        slots:
            /* if it will need 1000ms to finish */
            void doBusyThings()
            {
                ...
                ...
            }
        
        QTimer* timer = new QTimer(this);
        connect(timer, SIGNAL(tiermOut()), this, SLOT(doBusyThings()));
        timer->start(500);
        

        What happens to doBusyThings()?

        I mean doBusyThings() will be pushed into a queue and wait to execute? Or kill the running doBusyThings() and continue to execute the next?

        aha_1980A Offline
        aha_1980A Offline
        aha_1980
        Lifetime Qt Champion
        wrote on last edited by aha_1980
        #3

        Hi @Limer,

        just to add to @J-Hilk: The events will be queued, but during your long slot no events will be processed.

        That means, if you resize your window in that time, it will not be redrawn (Except you use ProcessEvents or start a local event loop).

        So there are two solutions:

        1. split doBusyThings() into smaller pieces that take much shorter time to execute
        2. use a separate thread to execute the long lasting tasks

        Regards

        Qt has to stay free or it will die.

        LimerL JonBJ 2 Replies Last reply
        5
        • aha_1980A aha_1980

          Hi @Limer,

          just to add to @J-Hilk: The events will be queued, but during your long slot no events will be processed.

          That means, if you resize your window in that time, it will not be redrawn (Except you use ProcessEvents or start a local event loop).

          So there are two solutions:

          1. split doBusyThings() into smaller pieces that take much shorter time to execute
          2. use a separate thread to execute the long lasting tasks

          Regards

          LimerL Offline
          LimerL Offline
          Limer
          wrote on last edited by
          #4

          @aha_1980 @J-Hilk Thanks a lot, i get it!

          1 Reply Last reply
          0
          • P Offline
            P Offline
            Pogot
            wrote on last edited by
            #5

            Hi @J-Hilk ,

            What happens in this case when a QEventLoop is used?

            If the execution time exceeds the QTimer delay, the current process will be killed in order to restart one?

            What solution can be envisaged so that the process is not killed despite the execution time and the QEventLoop?

            jsulmJ J.HilkJ 2 Replies Last reply
            0
            • P Pogot

              Hi @J-Hilk ,

              What happens in this case when a QEventLoop is used?

              If the execution time exceeds the QTimer delay, the current process will be killed in order to restart one?

              What solution can be envisaged so that the process is not killed despite the execution time and the QEventLoop?

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

              @Pogot said in If the execution time of slot function is greater than the interval of qtimer?:

              the current process will be killed in order to restart one?

              What process do you mean? Nothing will be killed. What will happen: the excution of the newer timer events will be delayed until event loop has a chance to be executed again.

              QEventLoop executes a local event loop, usually used to wait for soomething. Is usually bad design to use it.

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

              1 Reply Last reply
              0
              • P Pogot

                Hi @J-Hilk ,

                What happens in this case when a QEventLoop is used?

                If the execution time exceeds the QTimer delay, the current process will be killed in order to restart one?

                What solution can be envisaged so that the process is not killed despite the execution time and the QEventLoop?

                J.HilkJ Offline
                J.HilkJ Offline
                J.Hilk
                Moderators
                wrote on last edited by
                #7

                @Pogot said in If the execution time of slot function is greater than the interval of qtimer?:

                What happens in this case when a QEventLoop is used?

                depends where and how.

                IIRC a local QEventLoop does not process, naturally, the events of the global/main eventloop.

                So the events should still be queued up and stay that way.

                If the execution time exceeds the QTimer delay, the current process will be killed in order to restart one?

                nothing is killed or restarted everything happens sequentially. Sooo keep an eye out for stack overflows.

                What solution can be envisaged so that the process is not killed despite the execution time and the QEventLoop?

                I don't know, what exactly do you want to do!?

                What does process killed even mean ?


                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.

                1 Reply Last reply
                0
                • aha_1980A aha_1980

                  Hi @Limer,

                  just to add to @J-Hilk: The events will be queued, but during your long slot no events will be processed.

                  That means, if you resize your window in that time, it will not be redrawn (Except you use ProcessEvents or start a local event loop).

                  So there are two solutions:

                  1. split doBusyThings() into smaller pieces that take much shorter time to execute
                  2. use a separate thread to execute the long lasting tasks

                  Regards

                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote on last edited by JonB
                  #8

                  @aha_1980 said in If the execution time of slot function is greater than the interval of qtimer?:

                  just to add to @J-Hilk: The events will be queued, but during your long slot no events will be processed.

                  @aha_1980 , @J-Hilk , @jsulm
                  I could test this, but initially it seems easiest to just ask you guys. We are talking about QTimer timeout events. Let's say there are no threads or further event loops involved. Let's say the timeout is 1 second. Suppose that the first time the timeout slot is called it performs some blocking operation (e.g. sleep() or calculation) which takes 10 seconds.

                  According to "The events will be queued" that implies that when the event loop is next allowed to run, 10 seconds later, it will "notice" that 10 seconds have passed and generate 10 new timeout events at that instant. (Because, so far as I know, nothing is happening timer-/event-wise during the 10 seconds the main thread is busy/sleeping.) Is that really the case? I am thinking that having "missed" 10 (or 9) of the timeouts it will not generate them "in retrospect"? Or, does it really look at how much time has passed and generate multiple timeouts for all the "missing" periods, no matter how many there may be?

                  J.HilkJ 1 Reply Last reply
                  0
                  • P Offline
                    P Offline
                    Pogot
                    wrote on last edited by
                    #9

                    Sorry it's not process if I take the first example I wanted to ask if it killed the running doBusyThings() and run a new one

                    I'm asking because it's a behaviour I have. A singleShot Qtimer that calls a SLOT.
                    In the function there is a QEventLoop if at the time of exec() the timer is exceeded in this case the function is stopped and another restarts via the qt_static_metacall function.

                    Thanks

                    1 Reply Last reply
                    0
                    • JonBJ JonB

                      @aha_1980 said in If the execution time of slot function is greater than the interval of qtimer?:

                      just to add to @J-Hilk: The events will be queued, but during your long slot no events will be processed.

                      @aha_1980 , @J-Hilk , @jsulm
                      I could test this, but initially it seems easiest to just ask you guys. We are talking about QTimer timeout events. Let's say there are no threads or further event loops involved. Let's say the timeout is 1 second. Suppose that the first time the timeout slot is called it performs some blocking operation (e.g. sleep() or calculation) which takes 10 seconds.

                      According to "The events will be queued" that implies that when the event loop is next allowed to run, 10 seconds later, it will "notice" that 10 seconds have passed and generate 10 new timeout events at that instant. (Because, so far as I know, nothing is happening timer-/event-wise during the 10 seconds the main thread is busy/sleeping.) Is that really the case? I am thinking that having "missed" 10 (or 9) of the timeouts it will not generate them "in retrospect"? Or, does it really look at how much time has passed and generate multiple timeouts for all the "missing" periods, no matter how many there may be?

                      J.HilkJ Offline
                      J.HilkJ Offline
                      J.Hilk
                      Moderators
                      wrote on last edited by J.Hilk
                      #10

                      @JonB I wasn't sure myself so I did a small example/test myself:

                      #include <QTimer>
                      #include <QDebug>
                      
                      class TestTimer : public QObject
                      {
                          Q_OBJECT
                      public:
                          explicit TestTimer(QObject *parent = nullptr) : QObject(parent) {
                              QTimer *timer = new QTimer(this);
                              connect(timer, &QTimer::timeout, this, &TestTimer::handleTimeout);
                              timer->start(10); 
                          }
                      
                      public slots:
                          void handleTimeout() {
                              qDebug() << "Timeout event triggered at" << QDateTime::currentDateTime().toString("hh:mm:ss.zzz");
                              qDebug() << "Starting a long operation...";
                      
                              // Simulate a longer calculation
                              int result = 0;
                              for (int i = 0; i < 2000000000; ++i) { 
                                  result += i;
                              }
                      
                              qDebug() << "Long operation completed. Result:" << result;
                          }
                      };
                      
                      
                      int main(int argc, char *argv[])
                      {
                          QCoreApplication a(argc, argv);
                          TestTimer testTimer;
                          return a.exec();
                      }
                      
                      Timeout event triggered at "12:16:40.767"
                      Starting a long operation...
                      Long operation completed. Result: 321730048
                      Timeout event triggered at "12:16:46.064"
                      Starting a long operation...
                      

                      Contrary to my expectations, no event queue flooding occurred. Fascinating!


                      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.

                      JonBJ 1 Reply Last reply
                      1
                      • J.HilkJ J.Hilk

                        @JonB I wasn't sure myself so I did a small example/test myself:

                        #include <QTimer>
                        #include <QDebug>
                        
                        class TestTimer : public QObject
                        {
                            Q_OBJECT
                        public:
                            explicit TestTimer(QObject *parent = nullptr) : QObject(parent) {
                                QTimer *timer = new QTimer(this);
                                connect(timer, &QTimer::timeout, this, &TestTimer::handleTimeout);
                                timer->start(10); 
                            }
                        
                        public slots:
                            void handleTimeout() {
                                qDebug() << "Timeout event triggered at" << QDateTime::currentDateTime().toString("hh:mm:ss.zzz");
                                qDebug() << "Starting a long operation...";
                        
                                // Simulate a longer calculation
                                int result = 0;
                                for (int i = 0; i < 2000000000; ++i) { 
                                    result += i;
                                }
                        
                                qDebug() << "Long operation completed. Result:" << result;
                            }
                        };
                        
                        
                        int main(int argc, char *argv[])
                        {
                            QCoreApplication a(argc, argv);
                            TestTimer testTimer;
                            return a.exec();
                        }
                        
                        Timeout event triggered at "12:16:40.767"
                        Starting a long operation...
                        Long operation completed. Result: 321730048
                        Timeout event triggered at "12:16:46.064"
                        Starting a long operation...
                        

                        Contrary to my expectations, no event queue flooding occurred. Fascinating!

                        JonBJ Offline
                        JonBJ Offline
                        JonB
                        wrote on last edited by JonB
                        #11

                        @J-Hilk said in If the execution time of slot function is greater than the interval of qtimer?:

                        no event queue flooding occurred.

                        Indeed. But (unless I misunderstand) your output shows that 6 seconds passed in the long operation but only one timeout event was then generated at conclusion. (Please confirm this, it's not 100% clear from what you chose to show?) It did not (seem) to generate the 600 "missing" timeouts.

                        Assuming that is what you are showing then, as I suspected, all talk earlier about "So the events should still be queued up and stay that way." is, at least for QTimer timeouts, not at all the case.... Instead something like "you get a single timeout event on conclusion of a blocking operation no matter how many timeouts should have been generated during the blockage". Which is actually what I expected. QTimer timeouts work differently from, say, a mouse click or key press, where if I had done multiple ones during the blocking operation I would actually expect to see each one queued and acted on at conclusion.

                        aha_1980A 1 Reply Last reply
                        0
                        • JonBJ JonB

                          @J-Hilk said in If the execution time of slot function is greater than the interval of qtimer?:

                          no event queue flooding occurred.

                          Indeed. But (unless I misunderstand) your output shows that 6 seconds passed in the long operation but only one timeout event was then generated at conclusion. (Please confirm this, it's not 100% clear from what you chose to show?) It did not (seem) to generate the 600 "missing" timeouts.

                          Assuming that is what you are showing then, as I suspected, all talk earlier about "So the events should still be queued up and stay that way." is, at least for QTimer timeouts, not at all the case.... Instead something like "you get a single timeout event on conclusion of a blocking operation no matter how many timeouts should have been generated during the blockage". Which is actually what I expected. QTimer timeouts work differently from, say, a mouse click or key press, where if I had done multiple ones during the blocking operation I would actually expect to see each one queued and acted on at conclusion.

                          aha_1980A Offline
                          aha_1980A Offline
                          aha_1980
                          Lifetime Qt Champion
                          wrote on last edited by
                          #12

                          @JonB

                          Without digging into the code, my explanation for the behavior is the following:

                          During the event loop, it is checked if a timer is timed out and if that is the case, the slot is called. Timed out means: the current time is greater or equal to the expected timeout time. Then the next timeout time is calculated.

                          Nevertheless: blocking the event loop is bad behavior and will lead to all kind of problems. Furthermore, with changing implementation the behavior might be totally different in future.

                          Regards

                          Qt has to stay free or it will die.

                          JonBJ 1 Reply Last reply
                          1
                          • aha_1980A aha_1980

                            @JonB

                            Without digging into the code, my explanation for the behavior is the following:

                            During the event loop, it is checked if a timer is timed out and if that is the case, the slot is called. Timed out means: the current time is greater or equal to the expected timeout time. Then the next timeout time is calculated.

                            Nevertheless: blocking the event loop is bad behavior and will lead to all kind of problems. Furthermore, with changing implementation the behavior might be totally different in future.

                            Regards

                            JonBJ Offline
                            JonBJ Offline
                            JonB
                            wrote on last edited by
                            #13

                            @aha_1980 said in If the execution time of slot function is greater than the interval of qtimer?:

                            During the event loop, it is checked if a timer is timed out and if that is the case, the slot is called. Timed out means: the current time is greater or equal to the expected timeout time. Then the next timeout time is calculated.

                            Indeed so. So any talk of timeout events (but not others) being queued is incorrect.

                            J.HilkJ 1 Reply Last reply
                            0
                            • JonBJ JonB

                              @aha_1980 said in If the execution time of slot function is greater than the interval of qtimer?:

                              During the event loop, it is checked if a timer is timed out and if that is the case, the slot is called. Timed out means: the current time is greater or equal to the expected timeout time. Then the next timeout time is calculated.

                              Indeed so. So any talk of timeout events (but not others) being queued is incorrect.

                              J.HilkJ Offline
                              J.HilkJ Offline
                              J.Hilk
                              Moderators
                              wrote on last edited by J.Hilk
                              #14

                              @JonB yes and no

                              yes if you have long lasting "thread blocking functions", No, if a QEventLoop or QProcessEvents is used


                              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.

                              JonBJ 1 Reply Last reply
                              1
                              • J.HilkJ Offline
                                J.HilkJ Offline
                                J.Hilk
                                Moderators
                                wrote on last edited by
                                #15

                                Actually I'm not confident in that statement anymore, I do not know enough about that subject. I only rely on apparently outdated personal experiences :D


                                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.

                                1 Reply Last reply
                                0
                                • J.HilkJ J.Hilk

                                  @JonB yes and no

                                  yes if you have long lasting "thread blocking functions", No, if a QEventLoop or QProcessEvents is used

                                  JonBJ Offline
                                  JonBJ Offline
                                  JonB
                                  wrote on last edited by JonB
                                  #16

                                  @J-Hilk
                                  In the discussion here we are using neither. The OP's

                                      void doBusyThings()
                                      {
                                          ...
                                          ...
                                      }
                                  
                                  QTimer* timer = new QTimer(this);
                                  connect(timer, SIGNAL(tiermOut()), this, SLOT(doBusyThings()));
                                  timer->start(500);
                                  

                                  You wrote:

                                  that depends, do you do sketchy stuff in busyThings, like start a QEventLoop or call ProcessEvents ?
                                  If not, than the timeout events are queued and executed the next eventloop cycle.

                                  I am not intending to be picky, perhaps we have the same thing in mind. My point is only: even though the timeout here is 0.5 seconds if doBusyThings() takes 10 seconds (and does no event loop or processing) OP will get a single timeout event after 10 seconds not a plural (20) "timeout events are queued". Which could have been the Qt implementation but isn't. OTOH, (I believe) if it's, say, key press events which occur during the 10 seconds they will get all of them upon conclusion as they are genuinely queued. Just so OP is aware. If this is not important to them that is fine :)

                                  jeremy_kJ 1 Reply Last reply
                                  0
                                  • JonBJ JonB

                                    @J-Hilk
                                    In the discussion here we are using neither. The OP's

                                        void doBusyThings()
                                        {
                                            ...
                                            ...
                                        }
                                    
                                    QTimer* timer = new QTimer(this);
                                    connect(timer, SIGNAL(tiermOut()), this, SLOT(doBusyThings()));
                                    timer->start(500);
                                    

                                    You wrote:

                                    that depends, do you do sketchy stuff in busyThings, like start a QEventLoop or call ProcessEvents ?
                                    If not, than the timeout events are queued and executed the next eventloop cycle.

                                    I am not intending to be picky, perhaps we have the same thing in mind. My point is only: even though the timeout here is 0.5 seconds if doBusyThings() takes 10 seconds (and does no event loop or processing) OP will get a single timeout event after 10 seconds not a plural (20) "timeout events are queued". Which could have been the Qt implementation but isn't. OTOH, (I believe) if it's, say, key press events which occur during the 10 seconds they will get all of them upon conclusion as they are genuinely queued. Just so OP is aware. If this is not important to them that is fine :)

                                    jeremy_kJ Offline
                                    jeremy_kJ Offline
                                    jeremy_k
                                    wrote on last edited by
                                    #17

                                    @JonB said in If the execution time of slot function is greater than the interval of qtimer?:

                                    My point is only: even though the timeout here is 0.5 seconds if doBusyThings() takes 10 seconds (and does no event loop or processing) OP will get a single timeout event after 10 seconds not a plural (20) "timeout events are queued". Which could have been the Qt implementation but isn't.

                                    Emitting a single QTimer::timeout() in the case of a timer overrun is mentioned in the documentation.
                                    https://doc.qt.io/qt-6/qtimer.html#accuracy-and-timer-resolution:

                                    All timer types may time out later than expected if the system is busy or unable to provide the requested accuracy. In such a case of timeout overrun, Qt will emit timeout() only once, even if multiple timeouts have expired, and then will resume the original interval.

                                    Asking a question about code? http://eel.is/iso-c++/testcase/

                                    JonBJ 1 Reply Last reply
                                    3
                                    • jeremy_kJ jeremy_k

                                      @JonB said in If the execution time of slot function is greater than the interval of qtimer?:

                                      My point is only: even though the timeout here is 0.5 seconds if doBusyThings() takes 10 seconds (and does no event loop or processing) OP will get a single timeout event after 10 seconds not a plural (20) "timeout events are queued". Which could have been the Qt implementation but isn't.

                                      Emitting a single QTimer::timeout() in the case of a timer overrun is mentioned in the documentation.
                                      https://doc.qt.io/qt-6/qtimer.html#accuracy-and-timer-resolution:

                                      All timer types may time out later than expected if the system is busy or unable to provide the requested accuracy. In such a case of timeout overrun, Qt will emit timeout() only once, even if multiple timeouts have expired, and then will resume the original interval.

                                      JonBJ Offline
                                      JonBJ Offline
                                      JonB
                                      wrote on last edited by
                                      #18

                                      @jeremy_k Perfect, thanks.

                                      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