Process Synchronization¶
Critical Section Problem¶
The critical section is a segment of code where a process accesses shared resources.
flowchart TD
A(["Process enters"]) --> B["Entry Section\n(acquire lock)"]
B --> C["Critical Section\n(access shared resource)"]
C --> D["Exit Section\n(release lock)"]
D --> E["Remainder Section\n(other work)"]
E --> B
style C fill:#ef5350,color:#fff
style B fill:#f57c00,color:#fff
style D fill:#00897b,color:#fff
Requirements for a Solution¶
- Mutual Exclusion: Only one process in the critical section at a time
- Progress: Decision on who enters CS cannot be postponed indefinitely
- Bounded Waiting: Limit on times others can enter CS before a waiting process gets in
Race Conditions¶
A race condition occurs when two or more processes access shared data concurrently, and the final result depends on timing.
Semaphores¶
A semaphore S is an integer counter accessed through two atomic operations.
How a Semaphore Works¶
flowchart TD
subgraph wait_op["wait(S) — also called P() or down()"]
W1(["Process calls wait(S)"]) --> W2{"S > 0?"}
W2 -->|"Yes"| W3["S-- \ndecrement counter"]
W3 --> W4(["Process enters\ncritical section"])
W2 -->|"No"| W5["Process BLOCKS\nadded to wait queue"]
W5 --> W2
end
subgraph signal_op["signal(S) — also called V() or up()"]
S1(["Process calls signal(S)"]) --> S2["S++\nincrement counter"]
S2 --> S3{"Any process\nblocked?"}
S3 -->|"Yes"| S4["Wake up one\nwaiting process"]
S3 -->|"No"| S5(["Done"])
S4 --> S5
end
style W4 fill:#00897b,color:#fff
style W5 fill:#ef5350,color:#fff
style S4 fill:#7c4dff,color:#fff
Semaphore as a Traffic Light¶
sequenceDiagram
participant P1 as Process 1
participant S as Semaphore (S=1)
participant P2 as Process 2
P1->>S: wait(S)
Note over S: S=1 → S-- → S=0
Note over P1: Enters critical section
P2->>S: wait(S)
Note over S: S=0 → BLOCK P2
Note over P2: Waiting...
P1->>S: signal(S)
Note over S: S=0 → S++ → S=1\nWake up P2
Note over P1: Leaves critical section
S-->>P2: Wake up!
Note over P2: Enters critical section
P2->>S: signal(S)
Note over S: S=1
Note over P2: Leaves critical section
Types of Semaphores¶
Binary semaphore (mutex): Values 0 or 1: used for mutual exclusion
Counting semaphore: Any non-negative value: used to manage a pool of resources
Mutex (Mutual Exclusion)¶
A mutex is a binary semaphore used specifically for mutual exclusion.
Classic Synchronization Problems¶
Producer-Consumer Problem¶
flowchart LR
P["Producer"] -->|"add item"| B["Shared Buffer\n(size N)"]
B -->|"remove item"| C["Consumer"]
subgraph Semaphores
M["mutex = 1\n(protect buffer)"]
E["empty = N\n(free slots)"]
F["full = 0\n(filled slots)"]
end
style B fill:#1565c0,color:#fff
style M fill:#f57c00,color:#fff
style E fill:#00897b,color:#fff
style F fill:#7c4dff,color:#fff
sequenceDiagram
participant PR as Producer
participant SE as empty (N→)
participant SM as mutex (1)
participant SF as full (→0)
participant CO as Consumer
Note over SE,SF: Initial: empty=N, mutex=1, full=0
PR->>SE: wait(empty) — empty slot available?
PR->>SM: wait(mutex) — lock buffer
Note over PR: Add item to buffer
PR->>SM: signal(mutex) — unlock buffer
PR->>SF: signal(full) — notify consumer
CO->>SF: wait(full) — item available?
CO->>SM: wait(mutex) — lock buffer
Note over CO: Remove item from buffer
CO->>SM: signal(mutex) — unlock buffer
CO->>SE: signal(empty) — notify producer
Readers-Writers Problem¶
Rules:
- Multiple readers can read simultaneously
- Only one writer can write at a time
- No readers when a writer is writing
flowchart LR
R1["Reader 1"] --> DB[(Shared Data)]
R2["Reader 2"] --> DB
R3["Reader 3"] --> DB
W1["Writer"] -->|"exclusive access"| DB
style W1 fill:#ef5350,color:#fff
style DB fill:#1565c0,color:#fff
First readers-writers solution: Readers have priority (writers may starve)
Second readers-writers solution: Writers have priority (readers may starve)
Dining Philosophers Problem¶
flowchart TD
subgraph Table
P0(["Philosopher 0"]) --- C01["Chopstick 0"]
C01 --- P1(["Philosopher 1"])
P1 --- C12["Chopstick 1"]
C12 --- P2(["Philosopher 2"])
P2 --- C23["Chopstick 2"]
C23 --- P3(["Philosopher 3"])
P3 --- C34["Chopstick 3"]
C34 --- P4(["Philosopher 4"])
P4 --- C40["Chopstick 4"]
C40 --- P0
end
Problem: Deadlock if all philosophers pick up their left chopstick simultaneously.
Solutions:
- Allow at most 4 philosophers to sit at the table
- Pick up chopsticks only if both are available (atomic)
- Asymmetric: odd philosophers pick up left first, even pick up right first
Deadlock vs Starvation¶
flowchart LR
subgraph Deadlock
A["Process A\nwaiting for B"] -->|"holds resource"| B["Process B\nwaiting for A"]
B -->|"holds resource"| A
end
subgraph Starvation
HP["High-priority\nprocesses"] -->|"always get\nscheduled first"| LP["Low-priority\nprocess waits\nindefinitely"]
end
style A fill:#ef5350,color:#fff
style B fill:#ef5350,color:#fff
style LP fill:#f57c00,color:#fff
Deadlock: A set of processes are waiting for each other in a cycle - none can proceed
Starvation: A process waits indefinitely because other processes keep getting priority
Monitor¶
A monitor is a high-level synchronization construct that encapsulates:
- Shared data
- Procedures that operate on the data
- Synchronization primitives (automatic mutual exclusion)
Only one process can be active in the monitor at a time.