SpinLock handles "busy wait" in scenarios where you have frequent contention but with reasonably short waiting times by avoiding context switches and improving performance Imagine a situation in which a thread is trying to acquire access to a shared resource but the resource is already locked, so the thread has to wait until the lock is released. Here’s where thread synchronization comes into play. Thread synchronization is used to prevent multiple threads from accessing a shared resource concurrently. The Microsoft .Net Framework provides support for a range of synchronization primitives that can be used for controlling thread behavior and avoiding race conditions. Mutex and Spinlock are two popular synchronization mechanisms used to synchronize access to a shared resource. A SpinLock is an alternative to blocking synchronization. SpinLock (also known as “Busy Waiting”) is a mechanism that can be used to make a thread trying to acquire a lock wait in a loop till it can get access to the resource. Note that SpinLock can perform faster compared to Mutex since context switching is reduced. However, you should use SpinLocks only if the critical section is supposed to perform a minimal amount of work, i.e., the SpinLock is held for a very short period of time. SpinLocks are usually preferred in symmetric multiprocessor systems to constantly poll for availability of a resource in lieu of context switches. What is SpinLock and why is it needed? SpinLock performs busy waiting and can offer better performance when used in multi-core systems especially when it is cheap to wait in a loop and pool a resource rather than block on it. This is particularly helpful when the lock hold times are of a short duration. In other words, you can take advantage of SpinLock in multi-core systems to reduce the overhead involved in context switching if the time to be spent inside the critical section is small. A critical section may be defined as a data structure or a resource that is shared by multiple threads but one and only one thread can have access to it at any given point of time. It should be noted that holding SpinLock for longer duration would simply be a waste of the system’s resources and detrimental to the application’s performance. In essence, if you expect the blocking to be of a significant duration, SpinLock should never be used — use SpinLock only when the lock hold-times of a reasonably small duration. SpinLock are typically used when working with interrupts to perform busy waiting inside a loop till the resource is made available. SpinLock don’t cause the thread to be preempted, rather, it continues to spin till lock on the resource is released. Programming SpinLock in .Net Note that a SpinLock is defined as a struct in .Net, i.e., it is defined as a value type for performance reasons. Hence, if you are passing around a SpinLock instance, you should pass it by reference and not by value. In this section we will explore how we can program SpinLock in .Net. To implement SpinLock in .Net, you would need to take advantage of the SpinLock class available in the System.Threading namespace. The following code listing shows how you can use SpinLock in .Net. SpinLock spinLock = new SpinLock (true); bool isLocked = false; try { spinLock.Enter (ref isLocked); // Write your usual code here } finally { if (isLocked) spinLock.Exit(); } SpinWait Note that like SpinLock, SpinWait is also a struct and not a class. Similar to SpinLock, you can use SpinWait to write lock free synchronization code that can “spin” rather than block. SpinWait can be used to reduce resource consumption by performing CPU intensive spinning for 10 iterations post which it will yield the control by calling Thread.Yield and Thread.Sleep. In other words, SpinWait can be used to limit CPU-intensive spinning to a fixed number of iterations. The MSDN states: “System.Threading.SpinWait is a lightweight synchronization type that you can use in low-level scenarios to avoid the expensive context switches and kernel transitions that are required for kernel events.” To use SpinWait in your code, you can either leverage the SpinUntil() static method of the SpinWait struct, or, take advantage of its SpinOnce() non-static method. The following code snippet illustrates how SpinWait can be used. SpinWait spinWait = new SpinWait(); bool shouldSpin; while (!shouldSpin) { Thread.MemoryBarrier(); spinWait.SpinOnce(); } Related content feature 14 great preprocessors for developers who love to code Sometimes it seems like the rules of programming are designed to make coding a chore. Here are 14 ways preprocessors can help make software development fun again. By Peter Wayner Nov 18, 2024 10 mins Development Tools Software Development feature Designing the APIs that accidentally power businesses Well-designed APIs, even those often-neglected internal APIs, make developers more productive and businesses more agile. By Jean Yang Nov 18, 2024 6 mins APIs Software Development news Spin 3.0 supports polyglot development using Wasm components Fermyon’s open source framework for building server-side WebAssembly apps allows developers to compose apps from components created with different languages. By Paul Krill Nov 18, 2024 2 mins Microservices Serverless Computing Development Libraries and Frameworks news Go language evolving for future hardware, AI workloads The Go team is working to adapt Go to large multicore systems, the latest hardware instructions, and the needs of developers of large-scale AI systems. By Paul Krill Nov 15, 2024 3 mins Google Go Generative AI Programming Languages Resources Videos