Concurrency Part 7 — Semaphores trickery

This is the seventh part of the Concurrency series. For your convenience you can find other parts in the table of contents in Part 1 – Mutex performance in .NET

Last time we examined an interesting behavior of Mutex when it is abandoned. Today we will look into Semaphore.

Typical interview question is: what is the difference between a binary mutex and a semaphore? Exemplary answer is: mutex tracks owner, semaphore doesn’t. This is not always true, not all mutexes do that (ones that do are called recursive mutexes). However, based on this definition we can easily see a problem:

Run three instances and then kill first two. Last instance will never get the semaphore. Why? Because semaphore doesn’t track the owner so it cannot throw any exception when process dies.

Can we make it better? Yes:

We have an array of mutexes and track which one was acquired. Notice that id is also available in the exception so we know which one was freed by killing the process.