MacMusic  |  PcMusic  |  440 Software  |  440 Forums  |  440TV  |  Zicos
mutex
Search

How to use mutexes and semaphores in C#

Thursday February 13, 2025. 10:00 AM , from InfoWorld
Thread synchronization is used to prevent multiple threads from accessing a shared resource concurrently. The Mutex and Semaphore classes in.NET represent two of the most important related concepts. Let’s understand what both of these do and when we should use them.

Before we begin our discussion, let’s take a quick look at the basic concepts. A thread is the smallest unit of execution within a process. Multi-threading allows us to perform several tasks simultaneously. By synchronizing threads, we increase our application’s overall throughput and avoid problems like contention, deadlocks, and data loss.

Inter-process communication vs. inter-thread communication

When working with thread synchronization, you will often come across the terms “inter-process communication” and ”inter-thread communication.” Let’s understand the difference before we proceed with our discussion of mutexes and semaphores.

Inter-process communication refers to the communication between threads of separate processes on a given system, while inter-thread communication refers to the communication between threads of the same process. Keep in mind that the threads within a single process communicate significantly faster than threads in separate processes, because they are contained within the same memory space.

Mutexes and semaphores in.NET

A mutex is used to synchronize access to a protected resource or a “critical section” of code. (A critical section is code that must not be run by multiple threads at once.) Like a lock, a Mutex provides exclusive access to the resource, i.e., it allows one and only one thread to access the resource at a given point of time. Unlike a lock, a Mutex can be used to synchronize threads in different processes.

In.NET, we use the System.Threading.Mutex class to work with mutexes. When one thread acquires a lock on a Mutex object, all other threads are prevented from accessing the critical section until the lock on the Mutex object is released.

A semaphore is used to limit the number of threads that have access to a shared resource at the same time. In other words, a Semaphore allows you to implement non-exclusive locking and hence limit concurrency. You might think of a Semaphore as a non-exclusive form of a Mutex. In.NET, we use the System.Threading.Semaphore class to work with semaphores.

Create a mutex in C#

Let’s create a mutex object in.NET. Note that we use the WaitOne method on an instance of the Mutex class to lock a resource and the ReleaseMutex method to unlock it.

Mutex mutexObject = new Mutex(false, 'Demo');

try
{
if (!mutexObject.WaitOne(TimeSpan.FromSeconds(10), false))
{
Console.WriteLine('Quitting for now as another instance is in execution...');
return;
}
}
finally
{
mutexObject.ReleaseMutex();
}

Let us now implement a real-life code example that uses a mutex to synchronize access to a shared resource. The following code listing demonstrates how you can use a Mutex object in C# to synchronize access to a critical section that writes data to a text file.

public static class FileLogger
{
private const string fileName = @'D:ProjectsMyLog.txt';
public static void WriteLog(string text)
{
using var mutex = new Mutex(initiallyOwned: false, 'Global\log');

try
{
mutex.WaitOne(1000);
File.AppendAllText(fileName, text);
}
catch (AbandonedMutexException)
{
mutex.ReleaseMutex();
mutex.WaitOne(1000);
File.AppendAllText(fileName, text);
}
finally
{
mutex.ReleaseMutex();
}
}
}

In the FileLogger class shown above, an attempt is made to acquire a mutex by blocking the current thread for 1000 milliseconds. If the mutex is acquired, the text passed to the AppendAllText method as a parameter is written to a text file. The finally block then releases the mutex by making a call to the ReleaseMutex method.

Note that the ReleaseMutex method is always called by the same thread that has acquired the mutex.

Create a semaphore in C#

To create a Semaphore in C#, we create an instance of the Semaphore class. When creating a Semaphore instance, you need to pass two arguments to its argument constructor. The first argument indicates the number of initial resource entries, and the second argument specifies the maximum number of concurrent resource entries. Note that if you want to reserve all slots for the new threads that will be created, you should specify identical values for both of these parameters.

The following code snippet illustrates how you can create a semaphore in C#.

public static Semaphore threadPool = new Semaphore(3, 5);

The statement above creates a semaphore object named threadPool that allows a maximum of five concurrent requests. Note that the initial count is set to three, as indicated in the first parameter to the constructor. This implies that two slots are reserved for the current thread and three slots are available for other threads.

Now let’s write some code that will give our semaphore some threads to manage.

Create multiple threads in C#

The following code snippet shows how you can create and start 10 threads using the Thread class available in the System.Threading namespace. Note that the ThreadStart delegate refers to a method named PerformSomeWork. We’ll create the PerformSomeWork method next.

for (int i = 0; i

Create a thread pool in C#

Below is the code for the PerformSomeWork method. This method uses our semaphore, threadPool, to synchronize the 10 threads we created above.

private static void PerformSomeWork()
{
threadPool.WaitOne();
Console.WriteLine('Thread {0} is inside the critical section...', Thread.CurrentThread.Name);
Thread.Sleep(10000);
threadPool.Release();
}

Refer to the PerformSomeWork method given above. The WaitOne method is called on the Semaphore instance to block the current thread until a signal is received. The Release method is called on the same instance to release the semaphore.

Complete semaphore example in C#

And here is the complete code listing of our semaphore example for your reference.

class SemaphoreDemo
{
public static Semaphore threadPool = new Semaphore(3, 5);
public static void Main(string[] args)
{
for (int i = 0; i

Final thoughts

The Mutex and Semaphore classes allow us to write efficient multi-threaded applications in C#. Understanding how they work is critical to building systems that can access shared resources safely and efficiently. Whereas a mutex provides exclusive access to a resource by one and only one thread at a time, a semaphore provides non-exclusive access to a resource by a limited number of threads. A semaphore maintains a count of the threads to restrict access to the critical section.

Another important difference between mutexes and semaphores is that mutexes enforce thread ownership but semaphores do not. With a mutex, only the thread that acquires a lock can release it. With a semaphore, any thread could release a lock acquired by another thread. This means that a programming mistake could result in errors or exceptions in the application. Programmers must take extra care with semaphores.
https://www.infoworld.com/article/2245996/how-to-use-mutex-and-semaphore-in-c-sharp.html
News copyright owned by their original publishers | Copyright © 2004 - 2025 Zicos / 440Network
Current Date
Apr, Wed 2 - 16:50 CEST