Calling a function repeatedly using timer - c++

I am calling a function foo() continuously every second that checks the serial connection ,
Now my question is that what happens if one second passes and the function foo() is not completed the previous time it was called,will the previous function get executed first or will it get suspended etc
checkConnection =new QTimer(this);
checkConnection->start(1000);
connect(checkConnection, SIGNAL(timeout()), this, SLOT(foo()));

From the documentation at https://doc.qt.io/qt-5/qtimer.html:
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.
So it seems that only one timer event will exist in the queue at any one time.
That would mean your currently executing callback can take several seconds to complete and there would only be one queued in the meantime.

Related

Does a QTimer object run in a separate thread? What is its mechanism?

When I create a QTimer object in Qt 5, and start it using the start() member function, is a separate thread created that keeps track of the time and calls the timeout() function at regular intervals?
For example,
QTimer *timer = new QTimer;
timer->start(10);
connect(timer,SIGNAL(timeout()),someObject,SLOT(someFunction()));
Here, how does the program know when timeout() occurs? I think it would have to run in a separate thread, as I don't see how a sequential program could keep track of the time and continue its execution simultaneously. However, I have been unable to find any information regarding this either in the Qt documentation or anywhere else to confirm this.
I have read the official documentation, and certain questions on StackOverflow such as this and this seem very related, but I could not get my answer through them.
Could anyone explain the mechanism through which a QTimer object works?
On searching further, I found that as per this answer by Bill, it is mentioned that
Events are delivered asynchronously by the OS, which is why it appears that there's something else going on. There is, but not in your program.
Does it mean that timeout() is handled by the OS? Is there some hardware that keeps track of the time and send interrupts at appropriate intervals? But if this is the case, as many timers can run simultaneously and independently, how can each timer be separately tracked?
What is the mechanism?
Thank you.
When I create a QTimer object in Qt 5, and start it using the start()
member function, is a separate thread created that keeps track of the
time and calls the timeout() function at regular intervals?
No; creating a separate thread would be expensive and it isn't necessary, so that isn't how QTimer is implemented.
Here, how does the program know when timeout() occurs?
The QTimer::start() method can call a system time function (e.g. gettimeofday() or similar) to find out (to within a few milliseconds) what the time was that start() was called. It can then add ten milliseconds (or whatever value you specified) to that time and now it has a record indicating when the timeout() signal is supposed to be emitted next.
So having that information, what does it then do to make sure that happens?
The key fact to know is that QTimer timeout-signal-emission only works if/when your Qt program is executing inside Qt's event loop. Just about every Qt program will have something like this, usually near the bottom its main() function:
QApplication app(argc, argv);
[...]
app.exec();
Note that in a typical application, almost all of the application's time will be spent inside that exec() call; that is to say, the app.exec() call will not return until it's time for the application to exit.
So what is going on inside that exec() call while your program is running? With a big complex library like Qt it's necessarily complicated, but it's not too much of a simplification to say that it's running an event loop that looks conceptually something like this:
while(1)
{
SleepUntilThereIsSomethingToDo(); // not a real function name!
DoTheThingsThatNeedDoingNow(); // this is also a name I made up
if (timeToQuit) break;
}
So when your app is idle, the process will be put to sleep inside the SleepUntilThereIsSomethingToDo() call, but as soon as an event arrives that needs handling (e.g. the user moves the mouse, or presses a key, or data arrives on a socket, or etc), SleepUntilThereIsSomethingToDo() will return and then the code to respond to that event will be executed, resulting in the appropriate action such as the widgets updating or the timeout() signal being called.
So how does SleepUntilThereIsSomethingToDo() know when it is time to wake up and return? This will vary greatly depending on what OS you are running on, since different OS's have different APIs for handling this sort of thing, but a classic UNIX-y way to implement such a function would be with the POSIX select() call:
int select(int nfds,
fd_set *readfds,
fd_set *writefds,
fd_set *exceptfds,
struct timeval *timeout);
Note that select() takes three different fd_set arguments, each of which can specify a number of file descriptors; by passing in the appropriate fd_set objects to those arguments you can cause select() to wake up the instant an I/O operations becomes possible on any one of a set of file descriptors you care to monitor, so that your program can then handle the I/O without delay. However, the interesting part for us is the final argument, which is a timeout-argument. In particular, you can pass in a struct timeval object here that says to select(): "If no I/O events have occurred after (this many) microseconds, then you should just give up and return anyway".
That turns out to be very useful, because by using that parameter, the SleepUntilThereIsSomethingToDo() function can do something like this (pseudocode):
void SleepUntilThereIsSomethingToDo()
{
struct timeval now = gettimeofday(); // get the current time
struct timeval nextQTimerTime = [...]; // time at which we want to emit a timeout() signal, as was calculated earlier inside QTimer::start()
struct timeval maxSleepTimeInterval = (nextQTimerTime-now);
select([...], &maxSleepTimeInterval); // sleep until the appointed time (or until I/O arrives, whichever comes first)
}
void DoTheThingsThatNeedDoingNow()
{
// Is it time to emit the timeout() signal yet?
struct timeval now = gettimeofday();
if (now >= nextQTimerTime) emit timeout();
[... do any other stuff that might need doing as well ...]
}
Hopefully that makes sense, and you can see how the event loop uses select()'s timeout argument to allow it to wake up and emit the timeout() signal at (approximately) the time that it had previously calculated when you called start().
Btw if the app has more than one QTimer active simultaneously, that's no problem; in that case, SleepUntilThereIsSomethingToDo() just needs to iterate over all of the active QTimers to find the one with the smallest next-timeout-time stamp, and use only that minimum timestamp for its calculation of the maximum time-interval that select() should be allowed to sleep for. Then after select() returns, DoTheThingsThatNeedDoingNow() also iterates over the active timers and emits a timeout signal only for those whose next-timeout-time stamp is not greater than the current time. The event-loop repeats (as quickly or as slowly as necessary) to give a semblance of multithreaded behavior without actually requiring multiple threads.
Looking at the documentation about timers and at the source code of QTimer and QObject we can see that the timer is running in the thread/event loop that is assigned to the object. From the doc:
For QTimer to work, you must have an event loop in your application; that is, you must call QCoreApplication::exec() somewhere. Timer events will be delivered only while the event loop is running.
In multithreaded applications, you can use QTimer in any thread that has an event loop. To start an event loop from a non-GUI thread, use QThread::exec(). Qt uses the timer's thread affinity to determine which thread will emit the timeout() signal. Because of this, you must start and stop the timer in its thread; it is not possible to start a timer from another thread.
Internally, QTimer simply uses the QObject::startTimer method to fire after a certain amount of time. This one itself somehow tells the thread it's running on to fire after the amount of time.
So your program is fine running continously and keeping track of the timers as long as you don't block your event queue. If you are worried of your timer being not 100% accurate try to move long-running callbacks out of the event queue in their own thread, or use a different event queue for the timers.
QTimer object registers itself into EventDispatcher (QAbstractEventDispatcher) which than takes care to send events of type QTimerEvent every time there is timeout for a particular registered QTimer. For example, on GNU/Linux there is a private implementation of QAbstractEventDispatcher called QEventDispatcherUNIXPrivate that makes calculations taking in consideration the platform api for the time. The QTimerEvent are sent from QEventDispatcherUNIXPrivate into the queue of the event loop of the same thread where QTimer object belongs, i.e. was created.
QEventDispatcherUNIXPrivate doesn't fire a QTimerEvent because of some OS system event or clock, but because it periodically checkes the timeout when processEvents is called by the thread event loop where QTimer lives too. Se here: https://code.woboq.org/qt5/qtbase/src/corelib/kernel/qeventdispatcher_unix.cpp.html#_ZN27QEventDispatcherUNIXPrivateC1Ev

Does Qt Timer API stop and terminate the running slot? And how can I make it wait to get the timer slot execution completed?

I have just started working with QT, and found the nice feature of QTTimer which triggers the slot at the interval of given period. Some point in time, I came across two situations.
1) if the timer is in the pending state, stopping timer have no issues that i won't even move to 'running state'.
2) If the timer is already running ( assume it is a bit long process task), then i found the stop will not terminate/stop 'running state'.
My Question:
At any given point of time, if stop is invoked, i should make sure it is stopped if it is already running.
Example:
connect(&myTimer,SIGNAL(timeout()), this, SLOT(missionStarted()));
When i Stop like this:
myTimer.stop() -> It actually stops the next firing the signal, but it does not stop running state of missionStarted().
What i thought of a solution ?
myTimer.stop();
while (myTimer.isActive()) {
}
qDebug()<<" I am guaranteed that missionStarted() is no more running, will not run anymore" ;
Is the solution is a way to go?. please guide me.
Does Qt Timer API stop and terminate the running slot?
No. The timer stop does not terminate running slot.
And how can I make it wait to get the timer slot execution completed?
There several ways to do so: with the signal back to the object that has the timer, for instance:
void MyWorkerClass::mySlot()
{
doTheJob();
emit signalIamDone();
}
And the the object that has the timer can acknowledge the slot stopped by connecting to that signalIamDone:
connect(&workerObj, SIGNAL(signalIamDone()), &managerObj, SLOT(workerJobDoneSlot()));
The actual slot:
void MyManagerClass::workerJobDoneSlot()
{
doSomethingOnJobFinished();
}
I would also try to use condition variable wait if you had a manager and worker thread but it seems like everything is running on one main UI thread.
And mind that usually the worker slot is getting called on the same main thread as your manager object runs unless your manager object is specifically running in the context of own thread. So, unless told otherwise about threads, you always have it waiting on the slot finishing you just need to know that the wait is over or doSomethingOnJobFinished called.

SetTimer() pitfalls

I have a windowless timer (no WM_TIMER) which fires a callback function only once when a given time period is elapsed. It is implemented as a SetTimer()/KillTimer(). Time periods are small enough: 100-300 milliseconds.
Is that cheap enough (I mean performance) to call SetTimer()/KillTimer() pair for every such short time interval?
What if I have 100 such timers which periodically call SetTimer()/KillTimer()? How much Window timer objects may exist simultaneously in the system?
That is the question:
Use a bunch of such timer objects and rely on good Windows implementation of timers, or create one Windows timer object that ticks every, say, 30 milliseconds, and subscribe all custom 100-300 milliseconds one-time timers to it.
Thanks
The problem with timer messages as you are trying to use them is that they are low priority messages. Actually they are fake messages. Timers are associated with an underlying kernel timer object - when the message loop detects the kernel timer is signalled it simply marks the current threads message queue with a flag indicating that the next call to GetMessage - WHEN THERE ARE NO OTHER MESSAGES TO PROCESS - should synthesise a WM_TIMER message just in time and return it.
With potentially lots of timer objects, its not at all obvious that the system will fairly signal timer messages for all the timers equally, and any system load can entirely prevent the generation of WM_TIMER messages for long periods of time.
If you are in control of the message loop, you could use maintain your own list of timer events (along with GetTickCount timestamps when they should occur) and MSGWaitForMultipleObject - instead of GetMessage to wait for messages. Use the dwTimeout parameter to provide the smallest interval - from now - until the next timer should be signalled. So it will return from waiting for messages each time you have a timer to process.
And/Or you could use waitable timers - either on a GUI thread with MSGWaitForMultipleObjects, or just on a worker thread, to access the lower level timing functionality directly.
The biggest SetTimer() pitfall is that actually it is USER object (despite the fact it's not listed in MSDN USER objects list) hence it falls under Windows USER objects limitation - by default max 10000 objects per process, max 65535 objects per session (all running processes).
This can be easily proven by simple test - just call SetTimer() (parameters don't care, both windowed and windowless act the same way) and see USER objects count increased in Task Manager.
Also see ReactOS ntuser.h source and this article. Both of them state that TYPE_TIMER is one of USER handle types.
So beware - creating a bunch of timers could exhaust your system resources and make your process crash or even entire system unresponsive.
Here are the details that I feel you're actually after while asking this question:
SetTimer() will first scan the non-kernel timer list (doubly linked list) to see if the timer ID already exists. If the timer exists, it will simply be reset. If not, an HMAllocObject call occurs and creates space for the structure. The timer struct will then be populated and linked to the head of the list.
This will be the total overhead for creating each your 100 timers. That's exactly what the routine does, save for checking against the min and max dwElapsed parameters.
As far as timer expiration goes, the timer list is scanned at (approximately) the duration of the smallest timer duration seen during the last timer list scan. (Actually, what really happens is -- a kernel timer is set to the duration of the smallest user timer found, and this kernel timer wakes up the thread that does the checking for user timer expirations and wakes the respective threads via setting a flag in their message queue status.)
For each timer in the list, the current delta between the last time (in ms) the timer list was scanned and the current time (in ms) is decremented from each timer in the list. When one is due (<= 0 remaining), it's flagged as "ready" in its own struct and and a pointer to the thread info is read from the timer struct and used to wake the respective thread by setting the thread's QS_TIMER flag. It then increments your message queue's CurrentTimersReady counter. That's all timer expiration does. No actual messages are posted.
When your main message pump calls GetMessage(), when no other messages are available, GetMessage() checks for QS_TIMER in your thread's wake bits, and if set -- generates a WM_TIMER message by scanning the full user timer list for the smallest timer in the list flagged READY and that is associated with your thread id. It then decrements your thread CurrentTimersReady count, and if 0, clears the timer wake bit. Your next call to GetMessage() will cause the same thing to occur until all timers are exhausted.
One shot timers stay instantiated. When they expire, they're flagged as WAITING. The next call to SetTimer() with the same timer ID will simply update and re-activate the original. Both one shot and periodic timers reset themselves and only die with KillTimer or when your thread or window are destroyed.
The Windows implementation is very basic, and I think it'd be trivial for you to write a more performant implementation.

QTimer stops and starts by itself

Here is how I use QTimer:
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
timer->setInterval(1000);
timer->start();
Program monitors update() function and prints the current time in it. Normally it works as expected, it prints time at every second, but when program starts to process other jobs, there would be some breaks like 5 to 8 secs.
Qt Documentation mentions about accuracy issues like 1 ms, obviously I have another problem. Any ideas ?
QTimer (and all event-base message deliveries) is not interrupt driven. That means you are not guaranteed you will receive the event right when it's sent. The accuracy describes how the event is triggered, not how it's delivered.
If you are not doing threaded process on long job, call QCoreApplication::processEvents() periodically during the long process to ensure your slot gets called.
Your other jobs run for several seconds, and there's no event processing during these. You'd need to thread the jobs in order to get the responsiveness you want.

Does QThread::sleep() require the event loop to be running?

I have a simple client-server program written in Qt, where processes communicate using MPI. The basic design I'm trying to implement is the following:
The first process (the "server") launches a GUI (derived from QMainWindow), which listens for messages from the clients (using repeat fire QTimers and asynchronous MPI receive calls), updates the GUI depending on what messages it receives, and sends a reply to every message.
Every other process (the "clients") runs in an infinite loop, and all they are intended to do is send a message to the server process, receive the reply, go to sleep for a while, then wake up and repeat. Every process instantiates a single object derived from QThread, and calls its start() method. The run() method of these classes all look like this:
from foo.cpp:
void Foo::run()
{
while (true)
{
// Send message to the first process
// Wait for a reply
// Do uninteresting stuff with the reply
sleep(3); // also tried QThread::sleep(3)
}
}
In the client's code, there is no call to exec() anywhere, so no event loop should start.
The problem is that the clients never wake up from sleeping (if I surround the sleep() call with two writes to a log file, only the first one is executed, control never reaches the second). Is this because I didn't start the event loop? And if so, what is the simplest way to achieve the desired functionality?
Some classes in client code may need an event loop to be started. Why to use QThreads for clients if you don't have an event loop for the clients and you already using MPI?
A one liner answer to the question is - sleep and event loop are not related.
Sleep makes the calling thread sleep irrespective of whether it's being called from thread's overridden run() function or any other function for that matter. It makes no difference and there is no escape.
In fact, if exec() is called somewhere in run() (which the QThread's default implementation is) the control will not return to the caller.
The reason for the second log statement not getting written cannot be directly related with sleep() if the logger object is local or available to the run() function all the time. The control has to return to thread after designated amount of sleep is done. But meanwhile, the thread could lose control to transient objects like incoming connection.
Perhaps when this question was asked QThread::sleep() was a private function. Now with Qt 5, sleep or msleep or even usleep are public static functions.