Udostępnij za pośrednictwem


Don't let your thread sleep unless it really has to

Hello!

I -not so rarely- see a call to the Sleep API for polling purposes. Personally, I don’t recommend Sleep for polling. It is not only waste of computing resources but also wrong usage ( or usage without knowing the possible consequences ) can cause unexpected behavior.

Let’s start visiting the MSDN article about Sleep . Remarks section is what needs to be understood thoroughly:

“This function causes a thread to relinquish the remainder of its time slice and become unrunnable for an interval based on the value of dwMilliseconds. The system clock "ticks" at a constant rate. If dwMilliseconds is less than the resolution of the system clock, the thread may sleep for less than the specified length of time. If dwMilliseconds is greater than one tick but less than two, the wait can be anywhere between one and two ticks, and so on. To increase the accuracy of the sleep interval, call the timeGetDevCaps function to determine the supported minimum timer resolution and the timeBeginPeriod function to set the timer resolution to its minimum. Use caution when calling timeBeginPeriod, as frequent calls can significantly affect the system clock, system power usage, and the scheduler. If you call timeBeginPeriod, call it one time early in the application and be sure to call the timeEndPeriod function at the very end of the application.

After the sleep interval has passed, the thread is ready to run. If you specify 0 milliseconds, the thread will relinquish the remainder of its time slice but remain ready. Note that a ready thread is not guaranteed to run immediately. Consequently, the thread may not run until some time after the sleep interval elapses.”

 

Hence:

  • The thread is not guaranteed to resume execution after dwMilliSeconds.
  • Abuse of the request for higher clock resolution might stress the system performance.

 

Please read the experiences of developers in the discussion parts of the following forum articles:

https://stackoverflow.com/questions/7614936/can-i-improve-the-resolution-of-thread-sleep https://social.msdn.microsoft.com/Forums/en-US/ed169c61-465a-40c9-a9ef-d5b0c6138fdc/how-to-increase-the-timer-resolution-for-threadsleep?forum=netfxbcl https://stackoverflow.com/questions/23215970/system-threading-timer-vs-system-threading-thread-sleep-resolution-net-timer

 

If your solution really requires a timer and you are not going to use it for polling then the following article might help you to understand more accurate timers :

https://www.codeproject.com/Articles/1236/Timers-Tutorial

What usually is suggested is to remove the call to the Sleep function and change the logic such that an alertable wait is used. E.g. insteadof waking up every 10 msec and checking a registry key’s some value register to the registry change event. This way the thread won’t waste any CPU cycles.

 

I’ve listed some of the blog entries of Raymond Chen about Sleep and Polling. He has already explained them very well. Please have a look before you design a solution around Sleep and Polling.

Performance consequences of polling Consequences of the scheduling algorithm: Sleeping doesn’t always help Polling by sleeping versus polling by waiting with a timeout The dangers of sleeping on a UI thread Spurious wakes, race conditions, and bogus FIFO claims: A peek behind the curtain of WaitOnAddress The alertable wait is the non-GUI analog to pumping messages A thread waiting on a synchronization object could be caught napping

When can a thread receive window messages? Hidden gotcha in the thread pool sample program on MSDN

 

Happy coding!