9

I would be grateful for some pointers on how to wake a C++ 11 thread periodically (say every 100ms). The platform is Linux and the language C++. I came across this solution:

C++ 11: Calling a C++ function periodically

but there they call a callback function and then sleep for the timer interval. That means that the actual period is the function execution time + the interval. I want to call the callback at a constant interval, irrespective of its execution time.

I wonder if Boost would help? But I would prefer not to use it, as this project is not multi-platform and I want to minimize the use of third party libraries.

Perhaps combining a POSIX timer with a C++ thread is a way forward? I'm not sure exactly how that would work.

Any suggestions as to how to get started would be appreciated.

Community
  • 1
  • 1
DavidA
  • 2,053
  • 6
  • 30
  • 54
  • check http://stackoverflow.com/questions/14832139/call-function-periodically-without-using-threads-and-sleep-method-in-c – kTT Jun 14 '16 at 12:38
  • This is possibly what you want: https://stackoverflow.com/questions/37240834/how-can-we-make-a-loop-with-chronicle-statement-in-c/37241412#37241412 – Galik Jun 14 '16 at 14:28

5 Answers5

9

Use std::this_thread::sleep_until(), incrementing the absolute wakeup time by the fixed interval each time.

Jeremy
  • 5,055
  • 1
  • 28
  • 44
4

Here is a good article on this topic: Periodic Processing With Standard C++11 Facilities https://bulldozer00.com/2013/12/27/periodic-processing-with-standard-c11-facilities/

3

You need to measure the time your function take to execute and then sleep for the period less the execution time. Use std::this_thread::sleep_for to sleep for that amount of time that elapsed. Eg:

const auto timeWindow = std::chrono::milliseconds(100);

while(true)
{
    auto start = std::chrono::steady_clock::now();
    do_something();
    auto end = std::chrono::steady_clock::now();
    auto elapsed = end - start;

    auto timeToWait = timeWindow - elapsed;
    if(timeToWait > std::chrono::milliseconds::zero())
    {
        std::this_thread::sleep_for(timeToWait);
    }
}

NOTE: If your compiler supports it you can use 100ms rather than std::chrono::milliseconds(100). Mine doesn't :-(

Sean
  • 60,939
  • 11
  • 97
  • 136
2

For a pure C++ approach, without any implementation-specific functions, you can create a std::mutex and a std::condition_variable, lock the mutex, then use wait_for() to sleep on the conditional, for 100ms, or any other interval, in your thread.

For a more precise control over wake-up intervals, that takes into account the actual time your thread takes to execute, between pauses, use wait_until(), together with a suitable clock.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
1

I would call the function via std::async on a timer. However if your function regularly takes longer than the period you will rapidly consume resources. Also creating a new thread has a relatively expensive cost.

So you could time the duration length of the function via std::chrono::high_resolution_clock and then use wait_for to sleep the rest of the period.

graham.reeds
  • 16,230
  • 17
  • 74
  • 137