Step 05

Process Synchronization

Process synchronization is the mechanism provided by the operating system to ensure that concurrent processes execute in a controlled and orderly manner when accessing shared resources. It is a fundamental requirement of any multiprogramming or multitasking system.

Why synchronization is needed
Cooperating processes — processes that share data, files, or other system resources and therefore affect one another's execution
Race condition — a timing-dependent bug in which the final outcome depends on the order in which concurrent processes execute their instructions
Critical section — the small part of a program where shared data is accessed or modified, and where concurrency must be controlled
Mutual exclusion — a rule that ensures only one process can enter its critical section at a time, preventing inconsistent results
Semaphore — a synchronization primitive that uses atomic operations such as wait(S) and signal(S) to control access to shared resources
Mutex — a binary semaphore used as a lock, allowing only one process to hold it at a time and protecting critical sections

Real-world analogy: One ATM, two cards on the same account

Both of you check the balance ₹1000 at the same time and each withdraws ₹800. Since both read the old balance, the bank loses money. Locking the account while one transaction runs is exactly mutual exclusion.
Experiment: Create a race condition, then fix it

Process A

local = 0 · next line: A: read counter → local

Process B

local = 0 · next line: B: read counter → local

Shared variable

0

expected final value: 2

Click “Run next line” alternately between A and B to create an interleaving.

Requirements of a critical-section solution
  1. Mutual exclusion — at most one process inside the critical section.
  2. Progress — if no one is inside, a waiting process must be allowed in without unnecessary delay.
  3. Bounded waiting — a limit on how many times others can enter before a waiting process gets its turn (no starvation).
wait(S) {          signal(S) {
  while (S <= 0);     S = S + 1;
  S = S - 1;        }
}

do {
  wait(mutex);      // entry section
    critical section
  signal(mutex);    // exit section
    remainder section
} while (true);
Experiment: Producer–Consumer with a bounded buffer
empty
empty
empty
empty
empty
empty = 5 · full = 0 · mutex = 1

Buffer is empty. Produce an item to begin.

Quick quiz

1. A race condition occurs when:

2. wait(S) on a counting semaphore does what?

3. In the producer–consumer problem, the consumer blocks when:

Practice problem

Two processes each execute count++ 1000 times on a shared variable that starts at 0, with no synchronization. What is the minimum and maximum possible final value?