Skip to main content

Race condition; sleep() and wakeup()

Short answer

A race condition occurs when concurrent access to shared data yields an outcome dependent on execution order. Sleep() and Wakeup() are superior to busy waiting because a blocked process does not waste CPU cycles; the scheduler deschedules it, improving efficiency for long waits. Plain sleep/wakeup still suffers lost wakeups, requiring semaphores to atomically test-and-sleep.

What is race condition? Explain how Sleep() and Wakeup() solution is better than busy waiting solution for critical section problem.

Race condition

A race condition is a situation in which two or more processes read and write shared data and the final result depends on who runs exactly when. Example: in a print spooler, two processes read the same free slot in = 7 and both write their file name in slot 7; one job is lost. Race conditions are avoided by mutual exclusion.

Sleep() and Wakeup() versus busy waiting

Busy-waiting solutions (Peterson, TSL, strict alternation) keep a process in a loop testing a variable until it may enter. Sleep and wakeup are system calls: sleep() blocks the caller (moves it to the waiting state) and wakeup(p) moves process p back to the ready state.

PointBusy waitingSleep / Wakeup
CPU useWastes CPU cycles in the loopBlocked process uses no CPU
State of waiting processReady/runningBlocked (waiting)
EfficiencyPoor when wait is longGood for long waits
Priority inversionLow-priority holder may never run while high-priority process spinsAvoided, as the waiting process is blocked
ImplementationUser-level variablesNeeds kernel support

Producer-consumer example:

void producer() { while (TRUE) { item = produce();
    if (count == N) sleep();            /* buffer full */
    insert(item); count++;
    if (count == 1) wakeup(consumer); } }
void consumer() { while (TRUE) {
    if (count == 0) sleep();            /* buffer empty */
    item = remove(); count--;
    if (count == N-1) wakeup(producer);
    consume(item); } }

The producer sleeps when the buffer is full instead of spinning, and the consumer wakes it after removing an item. Caution: this plain version still has a race on count (a wakeup sent just before the other process sleeps is lost, and both may sleep forever); semaphores fix this by making the test and sleep atomic.

✓ Answer checked by Claude Opus 5.5 (high effort)

All Operating System chapter 3 questions →