Introduction
Semaphore is a kind of thread synchronization non-exclusive lock technique. It restricts the number of simultaneous threads of the shared resources up to maximum numbers. It defines the number of threads allowed to access a shared resource.
Example
There is a barber shop and only three barbers are available. The number of people wanting the hair-cut is six. So, the barbers can cut the hair of only three people at a time while rest of the people have to wait. When a barber finishes the haircut of one person, then only one of the waiting persons will get the haircut.
Movie Ticket Booking
Suppose, there is a cinema hall or theater with a seating capacity of around 200. Its tickets are sold online by 4 sellers. Each seller has to sell tickets for a global ticket value of 200. Sellers will stop selling the ticket once it gets finished. Each ticket seller has to show the number of sold tickets.
The solution to this problem statement is based on Thread Synchronization technique called "Semaphore".
Code explanation
- class Program
- {
- static int numTickets = 35;
- private const int numSellers = 4;
- static readonly SemaphoreSlim sema = new SemaphoreSlim(1);
-
- static void Main(string[] args)
- {
- Sell();
- Console.ReadKey();
- }
-
- public static void Sell()
- {
- Thread th = null;
- for (int i = 0; i < numSellers; i++)
- {
- sema.Wait();
- th = new Thread(SellTicket);
- th.Start(i);
- sema.Release();
- }
- if (th != null)
- {
- th.Join();
- }
- Console.WriteLine("All done");
- }
-
- private static void SellTicket(object name)
- {
- bool done = false;
- int numSoldByThisThread = 0;
-
- while (!done)
- {
- Thread.Sleep(1000);
- if (numTickets == 0)
- done = true;
- else
- {
- numTickets--;
- numSoldByThisThread++;
- Console.WriteLine("Seller {0} Sold One ticket ({1} Left)", name, numTickets);
- }
- }
-
- Console.WriteLine("{0} Noticed all tickets sold! (I Sold {1} myself)", name, numSoldByThisThread);
- }
- }
Output
Explanation
Here, we have global variables numTickets and numSellers. All sellers have to sell tickets from only variable value numTickets. This variable is shared among 4 threads because they want to sell ticket concurrently. And every seller should get an opportunity to access the ticket.
Here, resource "numSellers" containing with 35 tickets is only one and it is accessed by four threads. So, it will require thread synchronization technique. Semaphore is the best synchronization technique for such a situation.
In the below code, I have restricted the number of threads to one for the access of tickets at a time.
- static readonly SemaphoreSlim sema = new SemaphoreSlim(1);
SemaphoreSlim does synchronization by using Wait() and Release() keywords, like below.
- sema.Wait();
- th = new Thread(SellTicket);
- th.Start(i);
- sema.Release();
I have attached the zipped C# code for more details and clearity.
Conclusion
Semaphore is a very good non-exclusive lock synchronization technique. It is like a nightclub. It can limit the number of threads for synchronization as per the resource details.