Concurrency · intermediate

Semaphore

A semaphore maintains a count: acquire waits until it can decrement the count, and release increments it. Starting at N bounds outstanding acquisitions to N only when the protocol pairs each successful acquire with exactly one release.

Why it matters

Semaphores express capacity limits and signaling patterns that a single-owner mutex does not, such as bounding concurrent requests to a scarce resource.

Mental model

How to reason about semaphore

Permits are tokens. Work must take one token before entering; when none remain, it waits. Returning a token lets another waiter proceed.

Analogy

A parking lot issues one ticket per space. Cars may enter while tickets remain, and a departing car returns a ticket for the next arrival.

Examples

See the boundary, not just the happy path

Worked example · Limit database concurrency

semaphore(20); acquire before query; release after query

At most twenty callers use the constrained resource simultaneously, even if many more tasks exist.

Worked example · Signal available work

producer releases; consumer acquires

The count can represent produced but unconsumed items, allowing releases and acquires to occur in different execution contexts.

Useful contrast · Mutex ownership

a mutex is normally unlocked by its owner

A semaphore models permits rather than ownership; one context may release a permit that another context consumes, depending on the design.

Common mistakes

Misconceptions to remove early

Leaking a permit

If an error path skips release, available capacity permanently shrinks. Pair acquire and release with structured cleanup.

Using a binary semaphore as an interchangeable mutex

A count of one resembles exclusion, but ownership, priority handling, and misuse detection may differ. Choose the primitive matching the protocol.

Quick check

Can you predict the result?

1. What does a counting semaphore initialized to five permit?
  • Up to five successful outstanding acquisitions before another caller must wait
  • Exactly five operating-system threads total
  • Only one owner for the lifetime of the program
Answer: Up to five successful outstanding acquisitions before another caller must wait
2. Why must release run on every completion path?
Answer: A missing release leaks capacity and can eventually block all future acquisitions.

Keep building

Authoritative references

Make the idea retrievable.

Study this concept with spaced repetition, next to the commands where you use it.

Get Terminaster