Sobes.tech
Middle

How do mutex and semaphore differ from lock?

sobes.tech AI

Answer from AI

lock in C# is syntactic sugar for using Monitor.Enter and Monitor.Exit, wrapped in a try-finally block to ensure the lock is released. It provides exclusive access to a resource for one thread. Essentially, it is the simplest synchronization primitive at the object level.

Mutex is a synchronization primitive that can be used to provide exclusive access to a resource for one thread across multiple processes. It has the concept of ownership: only the thread that has acquired the mutex can release it.

Semaphore is a synchronization primitive that limits the number of threads that can access a resource simultaneously. It has a counter that decreases when access is granted and increases when it is released.

The main differences are summarized in the table:

Characteristic lock (Monitor) Mutex Semaphore
Scope of visibility Within a single process Between processes Between processes
Number of threads Only one Only one (owner) Limited number
Ownership Tied to a thread Tied to a thread Not tied to a thread
Usage Simple synchronization Synchronization between processes, named mutexes Limiting parallel access to a resource
Exceptions Does not require explicit handling of AbandonedMutexException Requires handling of AbandonedMutexException No AbandonedSemaphoreException
// Example of using lock
private readonly object _lockObject = new object();

public void DoSomethingWithLock()
{
    lock (_lockObject)
    {
        // Critical section
    }
}

// Example of using Mutex
using System.Threading;

private Mutex _mutex = new Mutex();

public void DoSomethingWithMutex()
{
    _mutex.WaitOne(); // Acquire mutex
    try
    {
        // Critical section
    }
    finally
    {
        _mutex.ReleaseMutex(); // Release mutex
    }
}

// Example of using Semaphore
using System.Threading;

private Semaphore _semaphore = new Semaphore(3, 3); // Allows 3 threads simultaneously

public void DoSomethingWithSemaphore()
{
    _semaphore.WaitOne(); // Acquire semaphore
    try
    {
        // Critical section, access limited to 3 threads
    }
    finally
    {
        _semaphore.Release(); // Release access
    }
}