Miro Bucko
Miro Bucko

Reputation: 1133

How to implement timer callback independent of the system time in C++ using boost

I need to create a timer which will call my function periodically (e.g. every 50ms). BUT the problem is I will need to change the system time while the timer is running. I would like to do this using boost so that the code is portable. Otherwise I am running it on Linux machine.

Things I have tried:

Both of these stop working when the system time is adjusted.

Question: Is there any way (using boost preferably) to create a callback timer which is independent of the system time? (Bonus karma for sample code)

Upvotes: 2

Views: 2034

Answers (1)

Stefan Weiser
Stefan Weiser

Reputation: 2292

Seems to be a bug under linux. You need to use a sleep method, that uses the CLOCK_MONOTONIC (boost::this_thread::sleep uses CLOCK_REALTIME). boost::this_thread::sleep_for with the boost chrono library should do this, because it uses the monotonic clock.

while (true) {
    // Call your function here.
    boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
}

Alternatively you could use boost::this_thread::sleep_until. With that function you could use a custom clock.

But the underlying CLOCK_MONOTONIC could be influenced by adjtime(). Therefore you could use CLOCK_MONOTONIC_RAW as a linux only alternative.

One more possibility: If you are able to use C++11 you could use std::chrono::steady_clock to get a strict monotonic clock.

auto start = std::chrono::steady_clock::now();
while (true) {
    std::cout << (start - std::chrono::steady_clock::now()).count() << std::endl;
}

The output here will not change, if the system clock gets adjusted. But do not use this with boost::this_thread. Use it with std::this_thread::sleep_for to get proper results.

The last possibility is just to use usleep or nanosleep.

But be aware, that you will not be able to interrupt the sleep with the last two options (STL and OS specific calls).

Upvotes: 3

Related Questions