Locking : Mutex vs Spinlocks

Locking : Mutex vs Spinlocks

Both mutexes and spinlocks are mechanisms used to protect shared data in concurrent programming, but they behave very differently in how a thread waits for access.

Mutex (Mutual Exclusion Lock) is kind of a key to use any resources in the system. If you have mutex, you can use the resource, if you don't wait till the mutex is released. Process goes to wait queue for that particular resource.

Spin lock is a mechanism in which the process needing a resource poll the lock on resource till it gets it. In other words, a spinlock is a lock where the thread continuously checks (spins) until the lock becomes available. It is also called as busy-waiting. Process will be busy in a loop till it gets the resource.

So we get the first difference there itself, the way both wait for the resource lock. In case of mutex, process goes in wait state and does not use processor while in spin-lock, process keeps on looping and hence uses the processor even while waiting.

When to use Mutex?

Use a mutex when:

• Critical section is long or unpredictable
• You want to save CPU usage
• You are in user-space applications
• Fair scheduling matters

Typical examples:

File access
• Database operations
• Complex computations inside critical section

When to use Spinlock?

Use a spinlock when:

• Critical section is extremely short
• You are in low-level or real-time systems
• Context switching cost is too high
• You cannot afford sleeping (e.g., interrupt context)

Typical examples:

• Operating system kernels
• Device drivers
High-performance concurrent data structures

C# Coding Examples

1. Mutex Example

Use a Mutex when:

• The lock may be held for a while
• Threads should sleep instead of burning CPU
• You need cross-process synchronization

Basic Mutex Example

using System;
using System.Threading;

class Program
{
    static Mutex mutex = new Mutex();
    static int counter = 0;

    static void Main()
    {
        Thread t1 = new Thread(Increment);
        Thread t2 = new Thread(Increment);

        t1.Start();
        t2.Start();

        t1.Join();
        t2.Join();

        Console.WriteLine($"Final Counter: {counter}");
    }

    static void Increment()
    {
        for (int i = 0; i < 100000; i++)
        {
            mutex.WaitOne();

            try
            {
                counter++;
            }
            finally
            {
                mutex.ReleaseMutex();
            }
        }
    }
}

Named Mutex (Cross-Process)

using System;
using System.Threading;

class Program
{
    static void Main()
    {
        bool createdNew;

        using var mutex = new Mutex(
            false,
            "Global\\MyAppMutex",
            out createdNew);

        if (!createdNew)
        {
            Console.WriteLine("Another instance is already running.");
            return;
        }

        Console.WriteLine("Application running...");
        Console.ReadLine();
    }
}

Useful for:

• Single-instance applications
• IPC synchronization

2. SpinLock Example

Use SpinLock when:

• Lock duration is extremely short
• Contention is rare
• Blocking would cost more than waiting
• Low-latency systems

A SpinLock repeatedly checks the lock in a loop ("spinning") instead of sleeping.

Basic SpinLock Example

using System;
using System.Threading;

class Program
{
    static SpinLock spinLock = new SpinLock();
    static int counter = 0;

    static void Main()
    {
        Thread t1 = new Thread(Increment);
        Thread t2 = new Thread(Increment);

        t1.Start();
        t2.Start();

        t1.Join();
        t2.Join();

        Console.WriteLine($"Final Counter: {counter}");
    }

    static void Increment()
    {
        bool lockTaken = false;

        try
        {
            for (int i = 0; i < 100000; i++)
            {
                lockTaken = false;

                spinLock.Enter(ref lockTaken);

                counter++;
            }
        }
        finally
        {
            if (lockTaken)
                spinLock.Exit();
        }
    }
}

Correct SpinLock Usage

A safer pattern:

bool lockTaken = false;

try
{
    spinLock.Enter(ref lockTaken);

    // critical section
}
finally
{
    if (lockTaken)
        spinLock.Exit();
}

This matters because SpinLock.Enter() can throw exceptions in some edge cases.

SpinLock with Thread Owner Tracking

SpinLock spinLock = new SpinLock(enableThreadOwnerTracking: true);

Benefits:

• Detects recursive locking bugs
• Easier debugging

Costs:

• Slightly slower

Performance Comparison

Mutex

Internally transitions to kernel mode:

Thread waits -> OS scheduler involved

Pros:

• Efficient for long waits
• Doesn't waste CPU

Cons:

• Context switching overhead

SpinLock

Pure busy waiting:

while(lock_not_free)
{
    CPU spins
}

Pros:

• Extremely low overhead
• Avoids context switches

Cons:

• Burns CPU cycles
• Terrible for long waits

Comparison of spin-lock and mutex

Spin-locks are best used when a piece of code cannot go to sleep state. Best example of such code would be interrupts request handlers.

Mutexes are best used in user space program where sleeping of process does not affect the system in catastrophic way.

Spin locks make sense when we have multi-processor systems or we have uni-processor system with preemption enabled, spin locks used in uni-processor systems without preemption enabled, may lead to deadlock where process goes on spinning forever.

Following table summarizes the above points.

Criteria Mutex Spinlock
Mechanism

Test for lock.

If available, use the resource

If not, go to wait queue

Test for lock.

If available, use the resource.

If not, loop again and test the lock till you get the lock

When to use

Used when putting process is not harmful like user space programs.

Use when there will be considerable time before process gets the lock.

Used when process should not be put to sleep like Interrupt service routines.

Use when lock will be granted in reasonably short time.

Drawbacks Incur process context switch and scheduling cost. Processor is busy doing nothing till lock is granted, wasting CPU cycles.

Contents related to 'Locking : Mutex vs Spinlocks'

How does a mutex work? What does a mutex cost?
How does a mutex work? What does a mutex cost?
Description of Lock, Monitor, Mutex and Semaphore
Description of Lock, Monitor, Mutex and Semaphore
Difference between Mutex and Semaphore
Difference between Mutex and Semaphore