Junior · Explain · Semaphore permits are not monitor ownership

Why does SemaphoreSlim require logical release ownership even when a maximum is configured?

Think through your answer before opening the explanation.

Runtime & concurrency

Reveal answer and reasoning

SemaphoreSlim tracks permits, not the identity of the thread or task that acquired them. A maximum can reject an extra release when the count is already full, but it cannot stop a wrong participant from releasing another operation's currently held permit. The application must pair successful acquisition with exactly one release owner. It also should not assume a general FIFO waiter order.

With one permit, a second same-flow zero-timeout wait returns false rather than receiving monitor-style reentrant ownership. A common wrong answer puts Release in every finally block, including cancellation before acquisition, or assumes the initial count is always the maximum even with the one-argument constructor. The desktop test shows cross-thread release is allowed, not that arbitrary release is correct. Shared semaphore lifetime, canceled waits, repeated cleanup, and fairness requirements all need a deliberate surrounding contract.

What a strong answer covers

  • Permits have no enforced thread or task identity.
  • An explicit maximum detects only some ownership mistakes.
  • Successful acquisition must have one logical release owner.

Common pitfall

Using a count maximum as a substitute for tracking who actually acquired a permit.

Follow-up questions

  1. What differs with the one-argument constructor?
  2. Why is CurrentCount not a reservation for a future wait?

Self-review

Choose what to revisit. These marks are your own assessment and are separate from lesson completion.

Primary references

Open lesson and code ↗

← All interview questions