E. W. Dijkstra devised the concept of a semaphore in the 1960s. Dijkstra thought about the semaphores in use by railroad lines to guard sections of track from concurrent access by trains, thus preventing train wrecks. In software a semaphore will guard a resource by only allowing some maximum number of threads to access the resource concurrently - other threads are blocked and need to wait.
If you want to learn more about semaphores, look in the MSDN documentation for CreateSemaphore – it’s part of the Win32 API. There are two ways get semaphore behavior in .NET. One is to write P/Invoke wrappers for the Win32 API in Kernel32. Another way is to write a managed component using synchronization primitives from the CLR. For example:
public class Semaphore
{
public Semaphore(int count)
{
this.count = count;
}
public void Wait()
{
lock(this)
{
while(count == 0)
{
Monitor.Wait(this);
}
count--;
}
}
public void Pulse()
{
lock(this)
{
count++;
Monitor.Pulse(this);
}
}
protected int count;
}
You’ll need to write P/Invoke wrappers if you need the additional capabilities offered by a true Win32 Semaphore. For example, a named semaphore that you can use across processes.
Trivia:
I’ve seen many a computer science textbook where the Wait method has the name P, and the Pulse method has the name V. Even today you’ll see libraries where the semaphore implementation has P and V methods. It always seemed rather cryptic to me but I understood these were the names Dijkstra himself gave the methods. I figured it was the 60s, bits were expensive, and poor Dijkstra probably had to punch out cards himself to write the functions. Since then I have learned P was short for the Dutch word proberen, meaning “to test”, and V was short for verhogen, meaning “increment”.

Twitter
Search
About
Learn C#