user2926577
user2926577

Reputation: 1827

Precision time sleep using chrono

I want my application to sleep for precisely 2000 microseconds:

#include <iostream>
#include <chrono>
#include <thread>

std::cout << "Hello waiter" << std::endl;
std::chrono::microseconds dura( 2000 );

auto start = std::chrono::system_clock::now();
std::this_thread::sleep_for( dura );
auto end = std::chrono::system_clock::now();

auto elapsed = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
std::cout << "Waited for " << elapsed.count() << " microseconds" << std::endl;

This results in

Waited for 2620 microseconds

Where does this discrepancy come from? Is there a better (more precise) method available?

Thanks!

Upvotes: 6

Views: 11779

Answers (2)

user2926577
user2926577

Reputation: 1827

Evidently, sleep_for is not precise at all. The working solution for this issue is to enter a while loop until the desired duration is reached. This make the application "sleep" for precisely 2000 microseconds.

bool sleep = true;
while(sleep)
{
    auto now = std::chrono::system_clock::now();
    auto elapsed = std::chrono::duration_cast<std::chrono::microseconds>(now - start);
    if ( elapsed.count() > 2000 )
        sleep = false;
}

Upvotes: 0

Philipp Cla&#223;en
Philipp Cla&#223;en

Reputation: 43989

Quoted from cppreference (see sleep_for):

This function may block for longer than sleep_duration due to scheduling or resource contention delays.

I think that is the most likely explanation. The details will depend on your environment, especially your OS.

In general, I see no portable way to avoid it (non-portable options include increasing thread priorities or reducing the nice level).

Another, however less likely, reason for time differences are external clock adjustments (e.g., caused by a ntp daemon). Using a steady_clock is a portable insurance against clock adjustments.

Upvotes: 3

Related Questions