AlgoMaster Logo

Mutex and Semaphores

13 min readUpdated December 16, 2025
Listen to this chapter
Unlock Audio

Mutex and Semaphores

A bathroom with a single lock. A parking lot with 50 spaces. A restaurant with 10 tables.

These real-world scenarios map directly to two fundamental synchronization primitives: mutex and semaphore.

A mutex is like the bathroom lock. Only one person can use it at a time. A semaphore is like the parking lot. Multiple cars can enter, but only up to the capacity.

In this article, we'll explore:

  • What is a Mutex and how it works
  • What is a Semaphore and its types
  • Key differences between them
  • When to use each
  • Implementation patterns and pitfalls

If you're enjoying this newsletter and want to get even more value, consider becoming a [paid subscriber](https://blog.algomaster.io/subscribe).

As a paid subscriber, you'll unlock all premium articles and gain full access to all [premium courses](https://algomaster.io/newsletter/paid/resources) on [algomaster.io](https://algomaster.io).

Unlock Full Access

1. What is a Mutex?

A Mutex (Mutual Exclusion) is a synchronization primitive that allows only one thread to access a resource at a time.

Think of it as a key to a room. Only the thread holding the key can enter. Other threads must wait until the key is returned.

Key Properties of Mutex

  1. Mutual Exclusion: Only one thread can hold the mutex at a time
  2. Ownership: The thread that locks must be the one to unlock
  3. Blocking: Threads waiting for the mutex are blocked (sleeping)

Basic Mutex Operations

The flow of mutex acquisition:

2. What is a Semaphore?

A Semaphore is a synchronization primitive that controls access to a resource by maintaining a count of available permits.

Think of it as a parking lot attendant. The lot has N spaces. Each car that enters takes a permit (decrementing the count). When a car leaves, it returns a permit (incrementing the count). When count reaches zero, new cars must wait.

Semaphore Operations

A semaphore has two fundamental operations:

Scroll
Operation
Also Called
Description

acquire()

wait(), P(), down()

Decrement count. Block if count is 0

release()

signal(), V(), up()

Increment count. Wake up waiting thread

3. Types of Semaphores

3.1 Binary Semaphore

A semaphore with only two states: 0 or 1. It behaves similarly to a mutex.

3.2 Counting Semaphore

A semaphore that allows multiple threads to access a resource, up to a specified limit.

Example: Limiting concurrent database connections

4. Mutex vs Semaphore

While binary semaphores and mutexes seem similar, they have important differences:

Comparison Table

Scroll
Aspect
Mutex
Semaphore

Ownership

Yes, only owner can unlock

No ownership concept

Count

Binary (0 or 1)

Can be any non-negative integer

Who can release

Only the acquiring thread

Any thread

Purpose

Protect critical sections

Limit concurrent access, signaling

Use case

Exclusive resource access

Connection pools, rate limiting

Recursive

Often supported

Not applicable

The Ownership Difference

This is the most important distinction:

This makes semaphores useful for signaling between threads, while mutexes are strictly for mutual exclusion.

5. Semaphore for Signaling

Because semaphores have no ownership, they can coordinate between different threads. One thread signals an event, another waits for it.

Example: Producer-Consumer Signaling

6. Common Use Cases

6.1 Mutex: Protecting Shared State

6.2 Semaphore: Connection Pool

6.3 Semaphore: Rate Limiting

6.4 Semaphore: Bounded Resource Access

7. Fairness

Both mutex and semaphore can be configured for fairness, meaning threads acquire them in the order they requested.

Scroll
Mode
Pros
Cons

Non-fair

Higher throughput

Possible starvation

Fair

No starvation, predictable

Lower throughput

8. Advanced: Reentrant Mutex

A reentrant (or recursive) mutex allows the same thread to acquire it multiple times without deadlocking.

The mutex tracks how many times it was locked by the owning thread. It only truly releases when the lock count reaches zero.

Semaphores are not reentrant. Each acquire decrements the count regardless of which thread called it.

9. Common Pitfalls

Pitfall 1: Forgetting to Release

Pitfall 2: Releasing Without Acquiring

Pitfall 3: Using Semaphore When Mutex is Needed

Pitfall 4: Deadlock with Multiple Resources

Pitfall 5: Wrong Initial Count

10. Choosing Between Mutex and Semaphore

Quick Reference

Scenario
Use

Protect shared variable

Mutex

Only one thread in critical section

Mutex

Limit database connections to 10

Semaphore(10)

Thread A signals Thread B

Semaphore(0) + release/acquire

Rate limit to N requests/second

Semaphore(N)

Object pool with fixed size

Semaphore(poolSize)

11. Summary

Mutex and Semaphore are fundamental synchronization primitives:

Key Differences:

Mutex
Semaphore

Only owner unlocks

Any thread can release

Binary (locked/unlocked)

Counting (0 to N permits)

For critical sections

For limiting access / signaling

Supports reentrancy

Not reentrant

When to Use:

  • Mutex: Protecting shared state, ensuring only one thread executes critical code
  • Counting Semaphore: Limiting concurrent access (pools, rate limiting)
  • Binary Semaphore: Signaling between threads

Best Practices:

  1. Use mutex for mutual exclusion (not binary semaphore)
  2. Always release in a finally block
  3. Be careful not to release without acquiring
  4. Consider fairness for preventing starvation
  5. Acquire multiple semaphores in consistent order to avoid deadlock

Thank you for reading!

If you found it valuable, hit a like and consider subscribing for more such content every week.

If you have any questions or suggestions, leave a comment.

This post is public so feel free to share it.

Share

P.S. If you're enjoying this newsletter and want to get even more value, consider becoming a [paid subscriber](https://blog.algomaster.io/subscribe).

As a paid subscriber, you'll unlock all premium articles and gain full access to all [premium courses](https://algomaster.io/newsletter/paid/resources) on [algomaster.io](https://algomaster.io).

Unlock Full Access

There are [group discounts](https://blog.algomaster.io/subscribe?group=true), [gift options](https://blog.algomaster.io/subscribe?gift=true), and [referral bonuses](https://blog.algomaster.io/leaderboard) available.

Checkout my [Youtube channel](https://www.youtube.com/@ashishps_1/videos) for more in-depth content.

Follow me on [LinkedIn](https://www.linkedin.com/in/ashishps1/) and [X](https://twitter.com/ashishps_1) to stay updated.

Checkout my [GitHub repositories](https://github.com/ashishps1) for free interview preparation resources.

I hope you have a lovely day!

See you soon, Ashish

References

Images Needed

[IMAGE 1: Mutex Concept] <!-- Single key/lock protecting a resource -->

[IMAGE 2: Semaphore Concept] <!-- Parking lot with N spaces analogy -->

[IMAGE 3: Binary vs Counting Semaphore] <!-- Visual comparison of permit counts -->

[IMAGE 4: Mutex vs Semaphore Comparison] <!-- Side-by-side feature comparison -->

[IMAGE 5: Producer-Consumer with Semaphores] <!-- Signaling flow between producer and consumer -->

[IMAGE 6: Decision Flowchart] <!-- When to use mutex vs semaphore -->