c++c++11operating-systemthread-sleep

why c++11 sleep_for microseconds actually sleep for millisecond?


I call this function in my centos 7 server.

I find std::this_thread::sleep_for(chrono::nanoseconds(1)) actually sleep for one ms, Is there any explanation? I think it may be caused by os setting?


Solution

  • You've got the question you asked covered by the other answers, but you also asked a question in the comments:

    Is there any simple method can ensure i sleep for 1us?

    Instead of calling sleep_for, yielding the thread's execution slot, you could busy-sleep. That is, loop until a certain amount of time has passed. It'll often get more accurate results at the cost of making that CPU thread unusable for doing anything else.

    Here's one example with a function called busy_sleep():

    // get a rough estimate of how much overhead there is in calling buzy_sleep()
    std::chrono::nanoseconds calc_overhead() {
        using namespace std::chrono;
        constexpr size_t tests = 1001;
        constexpr auto timer = 200us;
    
        auto init = [&timer]() {
            auto end = steady_clock::now() + timer;
            while(steady_clock::now() < end);
        };
    
        time_point<steady_clock> start;
        nanoseconds dur[tests];
    
        for(auto& d : dur) {
            start = steady_clock::now();
            init();
            d = steady_clock::now() - start - timer;
        }
        std::sort(std::begin(dur), std::end(dur));
        // get the median value or something a little less as in this example:
        return dur[tests / 3];
    }
    
    // initialize the overhead constant that will be used in busy_sleep()
    static const std::chrono::nanoseconds overhead = calc_overhead();
    
    inline void busy_sleep(std::chrono::nanoseconds t) {
        auto end = std::chrono::steady_clock::now() + t - overhead;
        while(std::chrono::steady_clock::now() < end);
    }
    

    Demo

    Note: This was updated after it was accepted since I noticed that the overhead calculation could sometimes get terribly wrong. The updated example should be less fragile.