You could busy-wait checking the time in a loop, until it reaches the time you're waiting for. That's obviously horrible, so don't do it. Sleeping for 10ms is somewhat better, but definitely poor design. (@Damon's answer has some good info.)
There's nothing wrong with using functions with sleep
in their name if that's the most useful thing for your program to do right then.
The suggestion to avoid sleep
is probably recommending against the general pattern of sleeping for a short time, checking if there's anything to do, then sleeping again. Instead, block waiting for an event with no timeout, or a very long timeout. (e.g. a GUI should wait for a keypress / click by calling a blocking function, with a timeout set to wake it up when it's time to autosave or whatever future thing is coming up next. You normally don't need a separate thread just to sleep, but you might if there's nowhere sensible to insert checks for the current time.)
Letting the OS wake you up when it's finally time to do anything is much better. This avoids context switches and cache pollution slowing down other programs and wasting power while you're spinning on short sleeps.
If you know there's nothing to do for some time, just sleep for that long with a single sleep. AFAIK, multiple short sleeps won't improve the accuracy of the wake-up time on mainstream OSes like Windows, Linux, or OS X. You might avoid an instruction-cache miss if your code had been waking up frequently, but if that amount of delay is a real problem you probably need a real-time OS and a much more sophisticated approach to timing. (Like wake up a fraction of a second early and spin-wait from there.)
If anything, a thread that's been sleeping for a long time is more likely to wake up exactly when it requested, while a thread that was running recently and slept for only 10ms might run into scheduler timeslice issues. On Linux, threads that have been asleep for a while get a priority boost when they do wake up.
Using a function without sleep
in the name that blocks for 1 second is no better than using sleep
or this_thread::sleep_for
.
(Apparently you want another thread to be able to wake you up. This requirement is buried in the question, but yes a condition variable is a good portable way to do that.)
If you want to use pure ISO C++11, then std::this_thread::sleep_for
or std::this_thread::sleep_until
are your best bet. These are defined in standard header <thread>
.
sleep(3)
is a POSIX function (like nanosleep
), not part of ISO C++11. If that's not a problem for you, then feel free to use it if it's appropriate.
For portable high-precision OS-assisted sleep-for-an-interval, C++11 introduced
std::this_thread::sleep_for(const std::chrono::duration<Rep, Period> &sleep_duration)
(The cppreference page has a code example of using it.)
Blocks the execution of the current thread for at least the specified sleep_duration.
This function may block for longer than sleep_duration due to
scheduling or resource contention delays.
The standard recommends that a steady clock is used to measure the
duration. If an implementation uses a system clock instead, the wait
time may also be sensitive to clock adjustments.
To sleep until a clock reaches a specified time (possibly taking into account changes / corrections to the system time):
std::this_thread::sleep_until(const std::chrono::time_point<Clock,Duration>& sleep_time)
Blocks the execution of the current thread until specified sleep_time
has been reached.
The clock tied to sleep_time
is used, which means that adjustments of
the clock are taken into account. Thus, the duration of the block
might, but might not, be less or more than sleep_time - Clock::now()
at the time of the call, depending on the direction of the adjustment.
The function also may block for longer than until after sleep_time
has
been reached due to scheduling or resource contention delays.
Notice that sleep_for
is meant to be unaffected by changes to the system clock, so it sleeps for that much real time.
But sleep_until
is supposed to let you wake up when the system clock reaches a given time, even if it did that by being adjusted (NTP or manual setting), if used with a clock other than steady_clock
.
Sleep gotchas: late / early wakeup
The caveats about possibly sleeping too long also apply to sleep
and nanosleep
, or any other OS-specific sleep or timeout (including the condition-variable approach in @Sebastian's answer), of course. It's unavoidable; a realtime OS can give you upper bounds on that extra delay, though.
You're already doing something like this with your 10ms sleeps:
Always assume that sleep
or whatever other function woke up late, and check the current time instead of using dead-reckoning in any case where that matters.
You can't build a reliable clock out of repeated sleep
.
e.g. don't build a count-down timer that sleeps for 1 second, decrements and displays a counter, then sleeps for another second. Unless it's just a toy and you don't care much about accuracy.
Some sleep functions such as POSIX sleep(3)
can also wake up early on a signal. If waking too early is a correctness problem, check the time and if necessary go back to sleep for the calculated interval. (Or use sleep_until
)