Please explain why Busy Waiting is generally frowned upon whereas Spinning is often seen as okay. As far as I can tell, they both loop infinitely until some condition is met.
-
1I think in a spinlock you actually do other stuff besides the waiting for its release... – Paul Stelian Jul 02 '16 at 09:40
-
2Don't spinlock unless you have a very good guarantee that you can acquire the lock in a microsecond or less. If it takes longer then it turns into busy-waiting and a bug. – Hans Passant Jul 02 '16 at 15:19
-
1a lock that uses busy waiting is called a spinlock --*Modern Operating System* – walkerlala Jul 02 '16 at 16:03
-
3"Loop infinitely ... until"? What do you think "infinite" means? – Kerrek SB Jul 02 '16 at 17:53
-
2This is more or less "a rat vs. a squirrel" type of deal: it's basically the same thing, but with a better PR. Spin lock is glorified busy-wait. Proceed with caution. – Sergey Kalinichenko Jul 02 '16 at 17:58
-
1@PaulStelian Exactly, unless the spinlock is written by an idiot. – David Schwartz Jul 03 '16 at 19:26
-
At app-level - don't do either. – No-Bugs Hare Sep 02 '17 at 06:24
-
See as well https://stackoverflow.com/questions/7488196/what-is-the-different-of-busy-loop-with-sleep0-and-pause-instruction which describes using the Intel pause instruction as well as https://stackoverflow.com/questions/1107593/what-are-trade-offs-for-busy-wait-vs-sleep – Richard Chambers Feb 12 '21 at 13:50
3 Answers
A spin-lock is usually used when there is low contention for the resource and the CPU will therefore only make a few iterations before it can move on to do productive work. However, library implementations of locking functionality often use a spin-lock followed by a regular lock. The regular lock is used if the resource cannot be acquired in a reasonable time-frame. This is done to reduce the overhead with context switches in settings where locks usually are quickly obtained.
The term busy-waiting tends to mean that you are willing to spin and wait for a change in a hardware register or a memory location. The term does not necessarily mean locking, but it does imply waiting in a tight loop, repeatedly probing for a change.
You may want to use busy-waiting in order to detect some kind of change in the environment that you want to respond to immediately. So a spin-lock is implemented using busy-waiting. Busy-waiting is useful in any situation where a very low latency response is more important than wasting CPU cycles (like in some types of embedded programming).
Related to this are the terms «lock-free» and «wait-free»:
So-called lock-free algorithms tend to use tight busy-waiting with a CAS instruction, but the contention is in ordinary situations so low that the CPU usually have to iterate only a few times.
So-called wait-free algorithms don't do any busy-waiting at all.
(Please note that «lock-free» and «wait-free» is used slightly differently in academic contexts, see Wikipedia's article on Non-blocking algorithms.)

- 259
- 1
- 6
-
+1 in general, but a bit of nitpicking: classical CAS pattern (read-CAS-var-calculate-new-value-try-CAS-if-failed-rinse-and-repeat) doesn't really qualify as busy-waiting (we're not really waiting for some external variable _to_change_ - which can take a loooong while, but rather we are waiting for the var to be stable from external interference - which never ever takes more than 2-3 iterations in practice); still - such CAS patterns don't qualify as "wait-free" :-(. – No-Bugs Hare Sep 02 '17 at 06:22
Standard versus spin mutexes: When a thread calls the function that locks and acquires a mutex, the function does not return until the mutex is locked. This is typical for event synchronization: a thread waiting for an event, namely, the fact that it has acquired mutex ownership. There are two ways in which this can happen:
• An idle wait: the thread waiting to lock the mutex is blocked in a wait state as explained in Chapter 2. It releases the CPU, which can then be used to run another thread. When the mutex becomes available, the runtime system wakes up and reschedules the waiting thread, which can then lock the now available mutex.
• A busy wait, also called a spin wait, in which a thread waiting to lock the mutex does not release the CPU. It remains scheduled, executing some trivial do nothing instruction until the mutex is released.
Standard mutexes normally subscribe to the first strategy, and perform an idle wait. But some libraries also provide mutexes that subscribe to the spin wait strategy. The best one depends on the application context. For very short waits spinning in user space is more efficient because putting a thread to sleep in a blocked state takes cycles. But for long waits, a sleeping thread releases its CPU making cycles available to other threads
I found this quite related from this source: https://www.sciencedirect.com/topics/computer-science/waiting-thread

- 21
- 1
When you understand the precise reason for a rule and have detailed platform and application knowledge, you know when it's appropriate to violate that rule. Spinlocks are implemented by experts who have a complete understanding of the platform they're developing on and the intended applications for spinlocks.
The problems with busy waiting are numerous, but on most platforms, there are solutions for them. Issues include:
- For CPUs with hyper-threading, a busy-waiting thread can starve another thread in the same physical core, even the very thread it's waiting for.
- When you busy wait, when you finally do get the resource you're waiting for, you take the mother of all mispredicted branches.
- Busy waiting interferes with CPU power management.
- Busy waiting can saturate inter-core buses as the thing you keep checking causes cache synchronization traffic.
But the people who design spinlocks understand all these issues and know precisely how to mitigate them on the platform. They don't write naive spinning code, they write intelligent spinning code.
So yes, they both loop infinitely until some condition is met, but they loop differently.

- 179,497
- 17
- 214
- 278