How to create a watchdog timer in Qt



  • I have a need for a watchdog timer, but can't figure out how to implement one.

    Any pointers or other help would be appreciated.


  • Qt Champions 2016

    hi
    What should the dog watch ?
    Can you say a little bit more about the function you are after?



  • I'm sorry, I thought that it was a common term. I guess not.

    A watchdog timer is one that counts down from a preset value. Incoming events can reset it to its original value and thereby preventing it from timing out. If there is an absence of triggers for long enough it times out and triggers an action.

    In my case, I have updates to some data that comes in bursts of indeterminate size. I would like to wait until there have been no updates for 10ms or so before updating the screen so they can all be handled in a batch. This would be much more efficient.

    I originally thought that a QTimer in singleshot mode would do the trick, but you can only trigger it once and there is no way to restart it.


  • Lifetime Qt Champion

    Hi,

    QTimer is the right tool. Make one member of your class, configure it as single shot and you can then restart it as needed.


  • Moderators

    @mjsurette said:

    there is no way to restart it

    You can restart the timer by calling [slot] void QTimer::start() again.



  • I must be missing something.

    This simple test program should have two timeouts, at 6 and 16 seconds in. But only one registers, and that's at the close of the program.

    #include <QCoreApplication>
    #include <QTimer>
    #include <QDebug>
    #include <QDateTime>
    
    #include <unistd.h>
    
    qint64 starttime;
    
    void timeout()
    {
        qDebug() << "timeout:" << QDateTime::currentMSecsSinceEpoch()-starttime;
    }
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        QTimer wd;
        wd.setSingleShot(true);
        QObject::connect(&wd,&QTimer::timeout,&timeout);
    
        starttime= QDateTime::currentMSecsSinceEpoch();
    
        qDebug() << "start:" << QDateTime::currentMSecsSinceEpoch()-starttime;
    
        for (int i=0;i<20;++i)
        {
            qDebug() << i;
            if (i==1 || i==11)
                wd.start(5000);
            sleep(1);
        }
        qDebug() << "done:" << QDateTime::currentMSecsSinceEpoch()-starttime;
        return a.exec();
    }
    
    

  • Lifetime Qt Champion

    The event loop is not running while you're in that for loop so your timer will only run once.


  • Moderators

    I must be missing something.

    Timer events are processed in the event loop (exec() call). You restart the timer 20 times before the loop even starts, so only the last one actually is processed (emits a timeout() signal).



  • Thanks for the explanation. I'll refactor my test program.


  • Qt Champions 2016

    @mjsurette said:

    In my case, I have updates to some data that comes in bursts of indeterminate size. I would like to wait until there have been no updates for 10ms or so before updating the screen so they can all be handled in a batch. This would be much more efficient.

    If I understand correctly you want to block event processing for a given amount of time, which doesn't exactly play well with QTimer. You can have a timed wait on a locked synchronization primitive for that:

    QSemaphore lock(0);
    lock.tryAcquire(1, 1000);  // Wait 1s for the semaphore to be released.
    

    Note: If I've misunderstood, and you want not to block the event loop, then this is certainly not the solution.

    PS. Another way for a blocking wait with event processing is by using a local event loop:

    QObject * emitter; //< This is the object that will emit a signal when something happened and the wait should interrupt
    
    QEventLoop loop;
    QObject::connect(emitter, SIGNAL(interruptWait()), &loop, SLOT(quit()));
    loop.exec();  // Wait until interruptWait() has been called
    

    Kind regards.



  • @mjsurette

    Just making sure you keep in mind the inherit limitations of qtimer. Qt is not a real time system. See the documentation http://doc.qt.io/qt-5/qtimer.html for more information.

    An alternative to batching by time, is to simply batch by size. It will be easier to write and the behaviour will probably be more consistent.


  • Qt Champions 2016

    @t3685 said:

    Qt is not a real time system. See the documentation http://doc.qt.io/qt-5/qtimer.html for more information.

    Nothing to do with Qt. It's the limitation of the underlying OS you have to take in mind.


  • Qt Champions 2016

    @mjsurette
    Just a note:
    WatchDog -is- a common term, i just wanted to hear what your overall
    goal was with it
    as there are many way to program a watchdog. :)


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.