C# Concurrency lesson–SemaphoreSlim

In windows we have two types of semaphores, local and named system semaphores.

You can think of a semaphore as a bounder in a nightclub, the responsibility is to only allow a number of people into the club at any one time.

.net has a lightweight semaphore, ‘SemaphoreSlim’ that can be used for local communication (that is to say, system synchronization is not supported)

using System;
using System.Threading;
using System.Threading.Tasks;
public class Example
{
private static SemaphoreSlim semaphore;
// A padding interval to make the output more orderly.
private static int audience;
public static void Main()
{
// Create the semaphore.
semaphore = new SemaphoreSlim(0, 3);
Console.WriteLine("{0} tasks can enter the semaphore.",
semaphore.CurrentCount);
const int SIZE = 10;
Task[] tasks = new Task[SIZE];
// Create and start five numbered tasks.
for(int i = 0; i <= SIZE-1; i++)
{
tasks[i] = Task.Run( () => {
// Each task begins by requesting the semaphore.
Console.WriteLine("Task {0} begins and waits for the semaphore, audience count: {1}",
Task.CurrentId, audience);
semaphore.Wait();
Interlocked.Increment(ref audience);
Console.WriteLine("Task {0} enters the semaphore , audience count: {1}", Task.CurrentId, audience);
Thread.Sleep(1000);
Interlocked.Decrement(ref audience);
Console.WriteLine("Task {0} releases the semaphore; previous count: {1} , audience count: {2}",
Task.CurrentId, semaphore.Release(), audience);
} );
}
// Wait for half a second, to allow all the tasks to start and block.
Thread.Sleep(500);
// Restore the semaphore count to its maximum value.
Console.Write("Main thread calls Release(3) --> ");
semaphore.Release(3);
Console.WriteLine("{0} tasks can enter the semaphore.",
semaphore.CurrentCount);
// Main thread waits for the tasks to complete.
Task.WaitAll(tasks);
Console.WriteLine("Main thread exits.");
}
}

If you run the code above (e.g. in .net core 2.1 project) you will be presented with the following result

What is happening is that all the tasks try get access to the semaphore, they are all initially blocked until

semaphore.Release(3);

is called which allows 3 tasks to enter at any one time.

Be the first to rate this post

  • Currently .0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Comments are closed