views:

1585

answers:

18
+29  Q: 

Is Sleep() evil?

First of all, there are many cases where Sleep() is misused, for example to "synchronize" threads or to regularily poll a value where a notification function would do (In Win32 WaitForSingleObject for example)

But what about other use cases? Is Sleep always evil? If no, what are good use cases for Sleep? If yes, why do almost all languages have some kind of Sleep statement?

PS: I've asked this question because of one of the comments of another question. There the OP states, that in his opinion, Sleep is to be avoided like goto.

+19  A: 

In the real world, it's not always practical to use the proper synchronisation primitives:

  • Sometimes you need to poll something until a condition is met, and there you use sleep to avoid soaking the machine.

  • Sometimes you actively want to sleep - for instance, when you want a thread to take minimal machine resources and you're on an operating system (cough Windows cough) that doesn't do a very good job of preventing low-priority threads from soaking the machine.

Edit in response to Kieveli's comment: I think you should implement proper signalling when you can. So a worker thread should do a blocking read on a queue rather than sleeping and polling. I'm saying that sometimes you're forced to interact with systems that preclude doing the right thing. I'm not saying you shouldn't bother doing the right thing when it's reasonably possible - "within half a second is good enough", maybe, but near-instantaneous would be noticeably better!

RichieHindle
Why implement signaling when the requirements don't force you to strict performance ratings. Within half of a second is good enough for a user to see responsiveness. Most of my multi-threaded worker classes will sleep for 250-500 ms to not bog down the CPU, then check for more work.
Kieveli
+2  A: 

IMHO you can only avoid a sleep() when you have a well written operating system and you are working within the normal realm of the OS.

When you have to work outside of an OS (eg. embedded software/firmware) and outside the normal realms (such as drivers) then you have no access to threading techniques because nothing is there to task switch for you. As such you have no choice but to do things like spinlocks and polled waits as there is no prememption to come help you.

Additionally if you are integrating against a non event based API then you sometimes have no choice but to poll for information so in that case your best option is to at least sleep and not spinlock to let the OS do something while you're waiting.

Spence
+7  A: 

The implementation of tail -f would require a sleep(). i.e. stat() the file, if it has changed, read in the differences, then sleep() for a bit......continue until interrupted.

I would consider this a valid use of sleep()

As an example on Linux, strace tail -f foo, settles down to

clock_gettime(CLOCK_REALTIME, {1247041913, 292329000}) = 0
nanosleep({1, 0}, NULL)                 = 0
fstat64(3, {st_mode=S_IFREG|0755, st_size=357, ...}) = 0
clock_gettime(CLOCK_REALTIME, {1247041914, 311933000}) = 0
nanosleep({1, 0}, NULL)                 = 0
fstat64(3, {st_mode=S_IFREG|0755, st_size=357, ...}) = 0
clock_gettime(CLOCK_REALTIME, {1247041915, 355364000}) = 0
....

OK this is nanosleep() but the same rules apply.

Solaris truss tail -f foo settles down to

read(0, 0x00024718, 65537)                      = 0
nanosleep(0xFFBFF1A0, 0xFFBFF198)               = 0
read(0, 0x00024718, 65537)                      = 0
nanosleep(0xFFBFF1A0, 0xFFBFF198) (sleeping...)
nanosleep(0xFFBFF1A0, 0xFFBFF198)               = 0
read(0, 0x00024718, 65537)                      = 0
Beano
As a matter of fact, most modern OSes have some kind of file change notification mechanism, i.e. "Wake me up if this file(s) change(s)". Linux has inotify, under Windows there's ChangeNotification, etc.. So polling a file is generally discouraged. Might be overkill for something like tail -f though...
sleske
See above edit.
Beano
+3  A: 

If you are using Sleep() to work with any case involving more than just the thread you are operating in, chances are you're doing something wrong...

That said, there are times when you want to pause processing, for example in an endless (or effectively so) working loop, to give other processes some breathing room.

Matthew Scharley
+2  A: 

Sleep is misused if it is used for "busy waiting". However in some cases, sleep is used in spin-locks or when you do not have an API that allows you to work with different event sources.

Artyom
+1  A: 

Sometimes, you do not want to refresh your display continually, for example in system or network monitors. Another example is watch(1) - how would you implement that without sleep?

phihag
+17  A: 

Ive found a good use for using Thread.Sleep(1000); to simulate latency when writing a callback in a web application.

A simple example with Microsoft's AJAX components is to put a button in an update panel... on the onclick handler use Thread.Sleep(), the update progress panel will then display for that amount of time.

Obvously remove the Thread.Sleep() when going live... :)

Chalkey
Yeah totally agree. Sometimes AJAX functionality processes too quickly and it's good to provide a wait. This gives a visual feedback to the user in the form of a wait image (or whatever you're using) on screen so they know something is changing / has changed.
Peanut
Yeah, especially in just a dev environment, chances are the callback will be pretty instant on your local machine, Sleep() gives you a chance to see your nice loading graphic in action, make sure its all correct etc :)
Chalkey
A: 

My most common use of Sleep is to illustrate problems in multithreaded code, but apart from that there are valid uses as mentioned in some of the other answers.

Brian Rasmussen
A: 

It's all about how you use it.

In some code we use at work, one developer put a sleep(5) 5 milliseconds, with the comment of 'sleep so my PC is still usable' which is fine, except our customers where complaining of speed performance. So I removed it, and the throughput doubled, but he put it back as sleep(0) complaining his machine became unresponsive when do large data loading testing. Groan, get a new dev PC

Where-as I'm have no problem is you really want to not load the system sleeping, or using sleep in conjunction with a polling type action.

Simeon Pilgrim
+1  A: 

In Java & .Net, sleep() is interruptable.

So, if you sleep(), and another thread interrupts you when desired (causing an InterruptedException to be thrown), there's nothing wrong with that.

I'm currently writing a polling mechanism over some external queue - and my code is basically:

while (true)
{
  items = takeFromQueue();
  if (items.size() == 0)
    sleep(1000);
}

And another thread can safely stop this thread by calling thread.interrupt();

ripper234
Why would one poll such a queue instead of using synchronization primitives (wait()/notify()) ? And you'll have to care about thread safety anyway with the sleeping approach
nos
Because the queue's API does not expose notify().
ripper234
+30  A: 

I actually believe the assertion you linked is correct. The problem is sleep is being used (as you noted) as an inefficient substitute for notification mechanisms. Sleep is always inferior to a properly implemented notification mechanism, If you are waiting for an event. If you actually need to wait a specific amount of time for something, then sleep is appropriate.

For example, in some network protocols, you make use of a technique known as exponential backoff, where if you detect a collision on the network, you want to wait a random (and exponentially increasing) amount of time before you retry. In this case sleep is appropriate because you're not trying to wait for an event to happen, you're trying to wait for a specific amount of time to pass.

Falaina
+2  A: 

The sleep() call can almost always be avoided. Given below are some scenarios in a program with an event loop and multiple threads, as this would be the most common scenario sleep() is (ab)used.

  1. As a monitoring/polling function (i.e. 'wait-every-100-ms-before-repeating-this-function') - a Timeout mechanism can replace the sleep. The Time-out essentially requests the application's main event handler to call a function after a certain time. This 'reminder' is stored in an internal queue, and is executed after the timer expires. e.g.:

    class DownloadMonitor 
    {
      int UpdateProgressBar();
      void Monitor()
      {
        if (UpdateProgressBar() < 100) 
        { 
          Application::SetTimeOut("100 ms", this, UpdateProgressBar); 
        }
      }
    }
    
    This applies for examples like "tail -f" too. A well implemented time-out (e.g. checking the file's modification time) will allow the user have control over program in between polls. One disadvantage of a time-out is that it is restricted to threads with event-loops (this is usually the main thread).

  2. As a thread sync mechanism - this is highly dangerous, as it estimates the time taken for a CPU to process something. Replace with binary semaphores.

A simple example of semaphores and time-outs:

  • A video-conversion software typically have separate threads for image analysis, disk IO and the UI (allowing commands like "Run in background", "Cancel", "Pause" etc).

  • The image analysis needs to complete before the disk IO is asked to write the converted part of the file to disk, and that needs to complete before the UI updates itself.

  • Allow both threads to run in a loop. The DiskIO thread starts by waiting at a "Finish Conversion" semaphore. The image-analysis can post this semaphore when a converted image is in the queue. The Disk IO thread writes this image to disk, updates a variable like "Percent Done", and waits at the semaphore again. The UI thread periodically reads the "Percent Done" variable using a time-out mechanism. The various UI statuses are set by the UI and checked at least once in each loop by the Conversion and Disk IO threads.

Probably the only valid use of sleep is to simulate activity. This is best used for testing and left out of customer builds.

Fox
+4  A: 

Same answer as for all the other "is it evil" questions.

It's a low-level operation. People sometimes use low-level operations to reinvent wheels which are already available as high-level operations. This is unwise, and you should make sure it's not what you're doing. But if you're actually programming at a low level, then you will probably be using low-level operations. Some high-level programmers will think you're evil or stupid or both. You know better, and since you're the one who writes their high-level platforms, they can either shut up or do it themselves.

Given a choice between a wicked contortion using a high-level construct, and a wicked contortion using a low-level construct, some people think you should always prefer the former. I don't really get their POV, but they are at least consistent, so you can't blame them unless the latter is demonstrably faster/smaller/better.

Good uses for sleep:

  • When you have to block until a certain time (or for a certain period). Your language/libraries/OS may or may not offer a blocking timer that does the job. If not, then sleep is the always-available option. If so, it will probably do exactly the same thing that the bog-standard sleep loop does anyway, so go with whatever is less code.

  • When implementing other primitives such as timers.

  • When you're using signals for asynchronous inter-thread or inter-process messaging on POSIX or whatever. You just sleep all the time, and signal handlers either do the work, or set state to tell you what work needs doing and you do it when you wake up. Of course you could use other APIs instead, but unless you actively prefer that API, then you'd just be avoiding sleep because some dude on the internet told you to. Maybe when he writes a programming language that doesn't have sleep, and is better than your current language, then you'll switch to that.

The main problem with sleep (aside from that it doesn't really do much interaction between threads, so is usually the wrong tool for jobs requiring that) is that even though you're not consuming any CPU time, you're still consuming resources because you have a thread sitting around doing nothing. Depending on platform, threads might be expensive. On a single-core system, the second thread of two is especially expensive, since if you can get rid of it most of your data synchronisation problems go away. So if you can reasonably design your app such that it never needs multiple threads, and never blocks except in some event loop, because everything is done with asynchronous messages, then do so, and you won't be needing sleep.

Steve Jessop
A: 

But what about other uses? Is Sleep always evil? If no, what are good use cases for Sleep?

How about you need to do something every 10 minutes, I don't see anything wrong with just putting your program/thread to sleep until it is time to work again.

Johan
+3  A: 

Aside from testing purposes like the one mentioned by Chalkey, I found that I never really need to call sleep on high level OS's like Linux, Windows and OS/X. Even in cases where the program is expected to simply wait for a set amount of time I use a wait function on a semaphore with a timeout, so that I can end the thread immediately by releasing the semaphore if something/somebody asks my program to terminate:

# [pseudo-code]

if wait_semaphore(exit_signal_semaphore, time_to_sleep)
  # another thread has requested this one to terminate
  end_this_thread
else
  # event timed-out; wait_semaphore behaved like a sleep function
  do_some_task
end
Romulo A. Ceccon
+3  A: 

I can't see it mentioned here, but sleep() is one pretty much sure way to yield your CPU time slice to more worthy process. When you sleep(), OS takes control and decides who should run next, this allows also other threads from same process have CPU time. This eases CPU pressure on single-CPU machine when multiple threads are spawned and a Controller waits for Workers to become ready.

Pasi Savolainen
+1  A: 

Windows: Normally if I need to make "sleep a thread" I would not use sleep(), instead I would use MsgWaitForMultipleObjects or similar which allows to specify a timeout while waiting for notifications. That way the thread can still react to any events (e.g. WM_QUIT) without the process having to wait for the thread to come out of sleep, check event and then quit.

Anders K.
+1  A: 

I made a device for reading Flash chips, that I control through the parallel port of my computer. I needed to wait for the data to propagate through the chips before sending another clock signal. So I used usleep().

Brad Gilbert