Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Incorrect Interval Timer for a CallBack function in C++

I find on the web this class to implement a callback function that asynchronously do some work while I’m on the Main thread. This is the class:

#include "callbacktimer.h"

    CallBackTimer::CallBackTimer()
    :_execute(false)
    {}

    CallBackTimer::~CallBackTimer() {
        if( _execute.load(std::memory_order_acquire) ) {
            stop();
        };
    }

    void CallBackTimer::stop()
    {
        _execute.store(false, std::memory_order_release);
        if( _thd.joinable() )
            _thd.join();
    }

    void CallBackTimer::start(int interval, std::function<void(void)> func)
    {
        if( _execute.load(std::memory_order_acquire) ) {
            stop();
        };
        _execute.store(true, std::memory_order_release);
        _thd = std::thread([this, interval, func]()
        {
            while (_execute.load(std::memory_order_acquire)) {
                func();
                std::this_thread::sleep_for(
                    std::chrono::milliseconds(interval)
                );
            }
        });
    }

    bool CallBackTimer::is_running() const noexcept {
        return ( _execute.load(std::memory_order_acquire) &&
                 _thd.joinable() );
    }

The problem here is that if I put a job to be done every millisecond I don’t know why but it is repeated every 64 milliseconds and not every 1 millisecond, this snippet get an idea:

#include "callbacktimer.h"

int main()
{
    CallBackTimer cBT;

    int i = 0;
    cBT.start(1, [&]()-> void {

        i++;

    });


    while(true)
    {
            std::cout << i << std::endl;
            Sleep(1000);
    }

    return 0;
}

Here I should see on the Standard Output: 1000, 2000, 3000, and so on. But it doesn’t…

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

It’s quite hard to do something on a PC in a 1ms interval. Thread scheduling happens at 1/64s, which is ~16ms.

When you try to sleep for 1 ms, it will likely sleep for 1/64s instead, given that no other thread is scheduled to run. As your main thread sleeps for one second, your callback timer may run up to 64 times during that interval.

See also How often per second does Windows do a thread switch?

You can try multimedia timers which may go down to 1 millisecond.

I’m trying to implement a chronometer in qt which should show also the microsecondo

Well, you can show microseconds, I guess. But your function won’t run every microsecond.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading