Small example showing QTimer slowing to a halt
-
@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
-
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 [...]
-
@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?
-
@KonstantinosTsakalis
I am not a realtime/embedded person. But at least read Accuracy and Timer Resolution, maybe also Alternatives to QTimer. Maybe aQt::PreciseTimer
or aQBasicTimer
would help?I don't think the default
QTimer
is to be relied on at 1ms, it's not intended for that. -
@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!
-
@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
-
@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.
-
@KonstantinosTsakalis QTimer has the singles shot property
https://doc.qt.io/qt-6/qtimer.html#singleShot-prop
simply set that to true -
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.
-
-
-