A mutex and a semaphore are both synchronization primitives, but they serve different purposes and have different semantics.
Mutex (Mutual Exclusion)
A mutex is a locking mechanism that ensures only one thread can access a resource at a time.
| Property | Description |
|---|---|
| Ownership | The thread that locks a mutex must unlock it |
| State | Binary — locked or unlocked |
| Purpose | Protect a critical section from concurrent access |
| Performance | Fast (user-space when uncontended) |
Typical use: Protect a shared data structure (linked list, hash table) from concurrent modification.
pthread_mutex_lock(&mutex);
// critical section — only one thread here at a time
shared_counter++;
pthread_mutex_unlock(&mutex);
Semaphore
A semaphore is a signaling mechanism with a counter. It can allow multiple threads to access a resource up to a limit.
| Property | Binary Semaphore | Counting Semaphore |
|---|---|---|
| Range | 0 or 1 | 0 to N |
| Use | Signaling (like mutex but no ownership) | Managing a pool of identical resources |
| Wait (P) | Decrement; block if 0 | Decrement; block if 0 |
| Signal (V) | Increment; wake a blocked thread | Increment; wake a blocked thread |
Typical uses: Binary — notify/wait between threads. Counting — control access to a pool of N database connections.
Key Differences
| Mutex | Semaphore | |
|---|---|---|
| Ownership | Yes — only owner can unlock | No — any thread can signal |
| Analogy | A locked room with one key | A parking lot with N spaces |
| Can be used for | Mutual exclusion | Both mutual exclusion and signaling |
| Priority inheritance | Usually supported | Not typically supported |
| Recursive locking | Often supported (same thread can lock again) | Not applicable |
Common Interview Scenario
// Mutex: protecting a shared counter
pthread_mutex_lock(&mtx);
count++;
pthread_mutex_unlock(&mtx);
// Binary semaphore: signaling worker from main thread
sem_post(&worker_sem); // "wake up, work is ready"
sem_wait(&worker_sem); // main thread waits for worker
Q: What’s the difference between a mutex and a binary semaphore?
A: The critical difference is ownership. A mutex must be unlocked by the same thread that locked it. A semaphore can be signaled by any thread. Mutexes are for mutual exclusion; semaphores are for signaling.
Q: When would you use a counting semaphore instead of a mutex?
A: When you have multiple identical resources — a pool of N database connections, N buffer slots, N printers. A mutex allows one thread in; a counting semaphore allows up to N threads.
Q: What happens if you unlock a mutex from a different thread?
A: It’s undefined behavior on most implementations — typically a crash or deadlock. This is why mutexes enforce ownership.
Q: Can a binary semaphore be used as a mutex?
A: Not safely. Without ownership tracking, you can accidentally signal from the wrong thread, leading to race conditions. Mutex is strictly for mutual exclusion; binary semaphore is for signaling.
Premium Content
Unlock Mutex vs Semaphore and all premium lessons with a subscription.
From ₹199.99/year — See plans