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. Small example showing QTimer slowing to a halt

Small example showing QTimer slowing to a halt

Scheduled Pinned Locked Moved Unsolved General and Desktop
17 Posts 8 Posters 3.1k Views
  • 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.
  • C Offline
    C Offline
    CuppoJava
    wrote on last edited by
    #1

    Hello.

    I managed to isolate my bug down to a very small test case, and was wondering whether I'm doing something wrong, or whether QT has a bug.

    I'm trying to set up a QTimer that just prints "tick" every 33ms. When I ran the program, it starts off doing that fine. After running for about 2 minutes, the ticks slow down to about once every 10 seconds.

    I feel I'm hitting a memory-leak, or some buffer is getting really long and I'm not clearing it.

    This is QT4.8 running on Mac OS-X 10.11.6.

    Thanks for your help!
    -Patrick

    In test.h:

    #ifndef TEST_H
    #define TEST_H
    #include <QObject>
    
    class Driver : public QObject{
      Q_OBJECT
    public:
      Driver();
    public slots:
      void tick();
    };
    
    #endif
    

    In test.cpp:

    #include "test.h"
    #include <iostream>
    #include <QApplication>
    #include <QTimer>
    using namespace std;
    
    Driver::Driver(){}
    void Driver::tick(){
      cout << "tick" << endl;
    }
    
    QApplication* app;
    Driver* driver;
    QTimer* timer;
    int main(int argc, char** argv){
      app = new QApplication(argc, argv);
      app->setQuitOnLastWindowClosed(false);
    
      driver = new Driver;
      timer = new QTimer;
      timer->setInterval(33);
      QObject::connect(timer, SIGNAL(timeout()), driver, SLOT(tick()));
      timer->start();
      
      return app->exec();
    }
    
    1 Reply Last reply
    0
    • T Offline
      T Offline
      TobbY
      wrote on last edited by
      #2

      Hello @CuppoJava
      Your code is perfectly fine. Didn't find any issue with memory leak. Maybe this Qt version contain bug for Mac OS.

      1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #3

        Hi and welcome to devnet,

        What version of Qt 4.8 ?

        By the way, there's no need for all these static variables that you are using especially app.

        int main(int argc, char** argv){
            QApplication app(argc, argv);
            app.setQuitOnLastWindowClosed(false);
        
            Driver driver;
            QTimer  timer;
            timer.setInterval(33);
            QObject::connect(&timer, SIGNAL(timeout()), &driver, SLOT(tick()));
            timer.start();
          
            return app.exec();
        }
        

        That way you don't have any memory leaks.

        On a side note, Qt 4.8 has reached end of line since a couple of years now, so if possible, you should rather start your new projects with Qt 5.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        3
        • C Offline
          C Offline
          CuppoJava
          wrote on last edited by
          #4

          Thanks very much for the help. I'll upgrade to QT5 to see whether that solves it. I'm working on a client project right now that's written in QT4, so if it turns out to be a bug in QT I'll have to find a workaround.

          1 Reply Last reply
          0
          • C Offline
            C Offline
            CuppoJava
            wrote on last edited by
            #5

            Just as an update, I upgraded to QT5 and the problem is still there. At this point, I almost think that it's a bug with the OSX terminal, except that I can't reproduce the problem using anything except QTimer. Does anyone have any suspicions that I can use as a starting point?

            Thanks very much!
            -Patrick

            1 Reply Last reply
            0
            • mranger90M Offline
              mranger90M Offline
              mranger90
              wrote on last edited by
              #6

              I would put an QElapsedTimer in the driver and look at the actual interval.
              If the actual interval is still at the expected time, but the display is off, then
              its the terminal not being able to keep up.

              J.HilkJ 1 Reply Last reply
              2
              • mranger90M mranger90

                I would put an QElapsedTimer in the driver and look at the actual interval.
                If the actual interval is still at the expected time, but the display is off, then
                its the terminal not being able to keep up.

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

                @mranger90 said in Small example showing QTimer slowing to a halt:

                I would put an QElapsedTimer in the driver and look at the actual interval.
                If the actual interval is still at the expected time, but the display is off, then
                its the terminal not being able to keep up.

                That's a great point, forcing a clear on the terminal may "reset" the delay


                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
                1
                • C Offline
                  C Offline
                  CuppoJava
                  wrote on last edited by
                  #8

                  That is a great tip. Thanks I'll run that experiment!

                  1 Reply Last reply
                  0
                  • C Offline
                    C Offline
                    CuppoJava
                    wrote on last edited by
                    #9

                    Okay. I ran the experiment. I started a QElapsedTimer at the same time as my QTimer (which is set to an interval of 33 ms) and printed out the elapsed time between each call. And it prints out the following, which shows a steady interval of 33ms followed by a sudden period where the interval jumps up to about 10s.

                    So I guess this rules out the OSX terminal as the cause of the slowdown. I verified that I see the same behaviour using both QT4 and QT5. Do you guys have any other ideas? I'm completely stumped.

                    Thanks!
                    -Patrick

                    [...]
                    tick 889
                    elapsed time: 33
                    tick 890
                    elapsed time: 33
                    tick 891
                    elapsed time: 32
                    tick 892
                    elapsed time: 32
                    tick 893
                    elapsed time: 32
                    tick 894
                    elapsed time: 32
                    tick 895
                    elapsed time: 32
                    tick 896
                    elapsed time: 10033
                    tick 897
                    elapsed time: 8457
                    tick 898
                    elapsed time: 4837
                    tick 899
                    elapsed time: 38
                    tick 900
                    elapsed time: 10030
                    tick 901
                    elapsed time: 10032
                    tick 902
                    elapsed time: 10031
                    [...]
                    
                    1 Reply Last reply
                    0
                    • K Offline
                      K Offline
                      KonstantinosTsakalis
                      wrote on last edited by
                      #10

                      @CuppoJava @SGaist Hi. Thank you both for your contribution. I'm having the same problem in Qt 6.2.4 . In my application which is running on an embedded device with a Linux kernel, we use a software watchdog which must be kicked by the GUI every 5 seconds.

                      Along with that, the data of the GUI are in communication with another processor. For the synchronization of the two, we use a QTimer with an interval of 1 ms. The application is running ok for some minutes, but eventually fails to kick the watchdog on time and is being restarted by systemd.

                      Using gammaray I was able to inspect the same behavior mentioned on this topic. The 'busy' timer is missing wakeups as the time passes by, and its interval is also being increased, leading to the delay I am mentioning.

                      The problem seems to go away if I increase the interval to 100 ms. Is there any restrictions to as how low a QTimer's interval can be?

                      I think I have located the issue being that the Event Loop of the main GUI thread is flooded by the QTimer's timeouts and thus cannot cope with processing the rest of the events on time. I have also considered moving this operation to another thread, but the data synchronization is not thread safe.

                      Do you have any updates on this topic and maybe how you solved it?

                      JonBJ 1 Reply Last reply
                      0
                      • K KonstantinosTsakalis

                        @CuppoJava @SGaist Hi. Thank you both for your contribution. I'm having the same problem in Qt 6.2.4 . In my application which is running on an embedded device with a Linux kernel, we use a software watchdog which must be kicked by the GUI every 5 seconds.

                        Along with that, the data of the GUI are in communication with another processor. For the synchronization of the two, we use a QTimer with an interval of 1 ms. The application is running ok for some minutes, but eventually fails to kick the watchdog on time and is being restarted by systemd.

                        Using gammaray I was able to inspect the same behavior mentioned on this topic. The 'busy' timer is missing wakeups as the time passes by, and its interval is also being increased, leading to the delay I am mentioning.

                        The problem seems to go away if I increase the interval to 100 ms. Is there any restrictions to as how low a QTimer's interval can be?

                        I think I have located the issue being that the Event Loop of the main GUI thread is flooded by the QTimer's timeouts and thus cannot cope with processing the rest of the events on time. I have also considered moving this operation to another thread, but the data synchronization is not thread safe.

                        Do you have any updates on this topic and maybe how you solved it?

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

                        @KonstantinosTsakalis
                        I am not a realtime/embedded person. But at least read Accuracy and Timer Resolution, maybe also Alternatives to QTimer. Maybe a Qt::PreciseTimer or a QBasicTimer would help?

                        I don't think the default QTimer is to be relied on at 1ms, it's not intended for that.

                        K 1 Reply Last reply
                        0
                        • JonBJ JonB

                          @KonstantinosTsakalis
                          I am not a realtime/embedded person. But at least read Accuracy and Timer Resolution, maybe also Alternatives to QTimer. Maybe a Qt::PreciseTimer or a QBasicTimer would help?

                          I don't think the default QTimer is to be relied on at 1ms, it's not intended for that.

                          K Offline
                          K Offline
                          KonstantinosTsakalis
                          wrote on last edited by
                          #12

                          @JonB Thank you for your answer. My problem is not really the resolution/accuracy of the timer, rather the fact that this fast timeout causes the whole application to delay its execution. But your reference helped me to find out that there are more than one types of QTimers, so thank you!

                          J.HilkJ 1 Reply Last reply
                          0
                          • K KonstantinosTsakalis

                            @JonB Thank you for your answer. My problem is not really the resolution/accuracy of the timer, rather the fact that this fast timeout causes the whole application to delay its execution. But your reference helped me to find out that there are more than one types of QTimers, so thank you!

                            J.HilkJ Online
                            J.HilkJ Online
                            J.Hilk
                            Moderators
                            wrote on last edited by
                            #13

                            @KonstantinosTsakalis have you considered making it not a continuously running but a "one shot" timer. And you simply restart the timer at the end of the connected slot ?

                            should prevent the event queue overflow


                            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.

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

                              @KonstantinosTsakalis have you considered making it not a continuously running but a "one shot" timer. And you simply restart the timer at the end of the connected slot ?

                              should prevent the event queue overflow

                              K Offline
                              K Offline
                              KonstantinosTsakalis
                              wrote on last edited by
                              #14

                              @J-Hilk That sounds indeed like something that can work.. I will try it, thank you!

                              I considered stopping the timer in the beginning of the slot lambda, and restarting it at the end, but then I would be altering the sender inside the slot, and this didn't seem a good practice to me.

                              J.HilkJ 1 Reply Last reply
                              0
                              • K KonstantinosTsakalis

                                @J-Hilk That sounds indeed like something that can work.. I will try it, thank you!

                                I considered stopping the timer in the beginning of the slot lambda, and restarting it at the end, but then I would be altering the sender inside the slot, and this didn't seem a good practice to me.

                                J.HilkJ Online
                                J.HilkJ Online
                                J.Hilk
                                Moderators
                                wrote on last edited by
                                #15

                                @KonstantinosTsakalis QTimer has the singles shot property
                                https://doc.qt.io/qt-6/qtimer.html#singleShot-prop
                                simply set that to true


                                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
                                1
                                • K Offline
                                  K Offline
                                  KonstantinosTsakalis
                                  wrote on last edited by
                                  #16

                                  Thank you all for your contribution. Your comments helped me to understand better how the event loop and QThread are working.

                                  It seems that my blocking point is not the communication with the other processor. The problem occurs when we log data to journald. The "why" is yet unclear, but for some reason logging to journald can occasionally take up to more than 10 seconds, so this is explaining why the application fails to kick the watchdog on time.

                                  I am now exploring other ways to implement this. Currently I have moved the logging functionality on a separate thread and this seems to work fine.

                                  I hope my description helps a future reader.

                                  Thank you.

                                  1 Reply Last reply
                                  0
                                  • JonBJ JonB referenced this topic on
                                  • M mliberato-pax referenced this topic on
                                  • M Offline
                                    M Offline
                                    mliberato-pax
                                    wrote on last edited by
                                    #17

                                    Posting here just in case someone comes across this -- I ~think~ I found the solution to be related to app nap, originally discovered here. My application was in python, so I was able to use appnope to ensure my python application wasn't throttled & this solved my manifestation of this problem.

                                    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