100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace

What is a Condition Variable?

Learn what a condition variable is — wait/signal, mutex pairing, and spurious wakeups — with a code example and interview questions.

mediumQ71 of 224 in Operating Systems Est. time: 6 minsLast updated:
Open Code Lab

Expected Interview Answer

A condition variable is a synchronization primitive that lets a thread block until another thread signals that some shared condition has become true, always used together with a mutex so the check-and-wait sequence stays race-free.

Unlike a mutex, which only enforces mutual exclusion, a condition variable lets threads sleep efficiently while waiting for a specific state change instead of busy-polling a flag. A thread calls wait on the condition variable while holding the associated mutex; the wait operation atomically releases the mutex and blocks the thread, then re-acquires the mutex automatically before returning once woken. Another thread that changes the shared state calls signal (wake one waiter) or broadcast (wake all waiters) after updating the state under the same mutex. Because operating systems can produce spurious wakeups and because a woken thread does not get to run immediately, the wait must always be wrapped in a loop that rechecks the actual predicate, not a single if-check — "while (!condition) wait(cv, mutex)" rather than “if (!condition) wait(cv, mutex)”.

  • Avoids busy-waiting by letting threads sleep until signaled
  • Pairs with a mutex to keep the check-and-wait sequence atomic
  • Supports both targeted (signal) and broadcast wakeups
  • Foundation for building bounded buffers, barriers, and thread pools

AI Mentor Explanation

A condition variable is like a twelfth man waiting off the field, holding the dressing-room door lock (mutex) while checking the scoreboard. Instead of constantly peeking outside, he releases the lock and waits until the captain rings a bell to signal a substitution is needed, then immediately re-grabs the lock before stepping out. He always rechecks the actual situation on waking, because the bell can occasionally ring for an unrelated reason (a spurious wakeup), so he loops on the real condition rather than trusting the bell alone.

Step-by-Step Explanation

  1. Step 1

    Acquire mutex

    The waiting thread locks the mutex that guards the shared predicate before checking it.

  2. Step 2

    Wait if condition false

    While the predicate is false, call wait on the condition variable, which atomically unlocks the mutex and blocks the thread.

  3. Step 3

    Signal or broadcast

    Another thread updates the shared state under the same mutex, then calls signal (one waiter) or broadcast (all waiters).

  4. Step 4

    Reacquire and recheck

    A woken thread automatically reacquires the mutex and rechecks the predicate in a loop before proceeding, guarding against spurious wakeups.

What Interviewer Expects

  • Understanding that a condition variable is always paired with a mutex
  • Knowing wait atomically releases the mutex and reacquires it on wakeup
  • Using a while-loop recheck instead of a single if-check
  • Distinguishing signal (one waiter) from broadcast (all waiters)

Common Mistakes

  • Using if instead of while around the wait call, missing spurious wakeups
  • Signaling the condition without holding the associated mutex
  • Confusing a condition variable with a semaphore (it has no memory of past signals)
  • Forgetting the state change and the signal must happen under the same lock

Best Answer (HR Friendly)

A condition variable lets a thread go to sleep efficiently until another thread tells it something it is waiting for has actually happened, instead of constantly checking in a loop. It always works together with a lock, and correct code rechecks the real condition after waking up rather than assuming the wakeup alone means it is safe to proceed.

Code Example

Producer-consumer using a condition variable and mutex
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t  not_empty = PTHREAD_COND_INITIALIZER;
int queue_size = 0;

void consumer(void) {
    pthread_mutex_lock(&mutex);
    while (queue_size == 0) {              /* loop, not if: guards spurious wakeups */
        pthread_cond_wait(&not_empty, &mutex);  /* unlocks mutex, sleeps, relocks on wake */
    }
    queue_size--;
    pthread_mutex_unlock(&mutex);
}

void producer(void) {
    pthread_mutex_lock(&mutex);
    queue_size++;
    pthread_cond_signal(&not_empty);       /* wake one waiting consumer */
    pthread_mutex_unlock(&mutex);
}

Follow-up Questions

  • Why must wait always be called while holding the associated mutex?
  • What is a spurious wakeup and why does the while-loop pattern guard against it?
  • When would you use broadcast instead of signal?
  • How does a condition variable differ from a semaphore?

MCQ Practice

1. What does calling wait on a condition variable do?

wait atomically unlocks the mutex and puts the thread to sleep; on wakeup it reacquires the mutex before returning to the caller.

2. Why should the wait call always be inside a while loop instead of an if statement?

A thread can wake without the condition truly being met, so the real predicate must be rechecked in a loop after every wakeup.

3. What is the key difference between signal and broadcast?

signal wakes a single waiting thread while broadcast wakes every thread currently blocked on that condition variable.

Flash Cards

What is a condition variable?A primitive letting a thread block until another thread signals a shared condition has changed, always paired with a mutex.

Why while, not if, around wait?To recheck the real predicate after a spurious or unrelated wakeup.

signal vs broadcast?signal wakes one waiter; broadcast wakes all waiters.

What does wait do to the mutex?Atomically releases it while blocking, and reacquires it automatically before returning.

1 / 4

Continue Learning