I see people doing this in some parts of heavily multi-threaded, multi-process application systems I work with. It seems to be done around debug lines:
std::cerr << "DEBUG: Reaching: " << __FUNCTION__ << " @ " << __LINE__ << std::endl;
sleep(0);
If I macro out sleep(0); (i.e. change it to ""), the debug output from the system seems to come in different order (less predictable), so I figure it makes the line come out sooner - but I thought std::cerr was unbuffered, and std::endl calls std::flush() anyway, so why would this be?
According to MSDN's documentation for Sleep: A value of zero causes the thread to relinquish the remainder of its time slice to any other thread that is ready to run. If there are no other threads ready to run, the function returns immediately, and the thread continues execution.
What Does the Linux sleep Command Do? The sleep command suspends the calling process of the next command for a specified amount of time. This property is useful when the following command's execution depends on the successful completion of a previous command.
Python time sleep function is used to add delay in the execution of a program. We can use python sleep function to halt the execution of the program for given time in seconds. Notice that python time sleep function actually stops the execution of current thread only, not the whole program.
sleep in Java. Thread. sleep() method can be used to pause the execution of current thread for specified time in milliseconds.
Basically, it yields control back to the scheduler, and lets you be re-scheduled instantly. That said, it's basically a hack to try and fool the operating system into doing something.
And it's never a good idea to fool the operating system.
If the system is suitably underloaded, then going to sleep will mean the OS gets control and lets the I/O queue flush, so it would have that effect. Sometimes. Depending.
Exactly what it's doing depends on details of the implementation that, frankly, you can't depend upon.
It perturbs the scheduler in a difficult-to-predict way.
Typically the result will be similar to a call to pthread_yield()
- you give up your timeslice. The result of this is that, under heavy debug print load, you'll be less likely to be preempted in the middle of writing to cerr (ie, between those <<
s), since you'll be at the start of a timeslice after the last debug print, and thus you're less likely to have multiple threads overwriting each other's output (ie, getting something like DEBUG: REACHING: foo() @ DEBUG: REACHING bar()17 @ 24
).
That said, this method is unreliable - it's perturbing the scheduler, not asking for specific semantics. It's also slow - unconditionally entering the kernel to yield (and possibly bouncing control among multiple threads too frequently). And it's less likely to work properly on a multicore CPU.
It would be better to put a mutex over all debug output like this. That said, since this is debug code, it's not surprising that the author may have used a quick-and-dirty hack to get it working just well enough to debug whatever problem they were having.
On most platforms, sleep(0)
causes the scheduler to treat the current thread more or less as if it had used up its timeslice. Typically this means that, if possible, another thread in the same process will be scheduled on that core if one is ready-to-run. As you noted, it tends to make scheduling slightly more predictable. To me, that seems counter-productive when debugging.
I agree with Nemo's comment that it's much the same as pthread_yield
. It does have some legitimate uses, but it's sometimes used erroneously as a way to provide more fairness or reduce latency. Typically it just makes performance worse because a context switch blows out the caches.
I've looked at the other answers and I agree with the general sense of befuddlement. My bet is that there is no good reason for it other than that someone thought that more predictable scheduling was a good thing. (It's not. Flexibility is good. The more requirements you put on the scheduler, the more it has to sacrifice to meet those requirements. If you impose requirements that aren't actually required, you trade performance for nothing at all.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With