0% found this document useful (0 votes)
3 views

L-08

The document discusses classical synchronization problems in computer science, including the producer/consumer problem, dining philosophers, and the reader/writer problem. It outlines various solutions using critical regions, semaphores, and monitors to manage resource sharing and prevent issues like starvation. Each problem is illustrated with examples and the importance of proper synchronization in multithreaded applications is emphasized.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

L-08

The document discusses classical synchronization problems in computer science, including the producer/consumer problem, dining philosophers, and the reader/writer problem. It outlines various solutions using critical regions, semaphores, and monitors to manage resource sharing and prevent issues like starvation. Each problem is illustrated with examples and the importance of proper synchronization in multithreaded applications is emphasized.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 23

Classical Synchronization Problems

1. The producer/consumer problem (the bounded buffer


problem)
2. The dining philosophers
3. The reader/writer problem
The Bounded Buffer Problem

head tail

A circular buffer of limited capacity.


Queue access: Add to tail, remove from head
Models consumer/producer interactions
n : number of slots, nitems : number of items
Why Important?

It occurs in many situations in real systems:


Network interfaces
I/O controllers
Message-passing
others
Solution using Critical Regions

Producer:
region v when nitems < n do
buf [tail++ % n] = item;
nitems++;
Consumer
region v when nitems > 0 do
item = buf [head++ % n];
nitems--;
return item;
Solution using Monitors

Monitor BoundedBuffer
char buf [n];
int nitems;
int tail, head;
condition empty, full;
// initialization
nitems = tail = head = 0;
Solution with Monitors (cont’d)

Produce(item) Consume(item)
if(nitems == n) if(nitems == 0)
full.wait; empty.wait;
buf [tail++ % n]=item; item = buf [head++ % n];
nitems++; nitems--;
empty.signal; full.signal;
Dining Philosophers
Definition

A philosopher alternates between


thinking:
Gives up the two chopsticks on right & left
eating
Picks up the two chopsticks on right & left
Picks up chopsticks one at a time
If chopstick is in use, must wait until neighbor thinks and then picks it
up
Why Important?

It models competition for resources between threads or


processes
Key requirement:
Philosophers should not starve!!!
A Solution Using Semaphore

Semaphore Chopstick[5]; // initialized to 1


while(1) {
P(Chopstick[i]);
P(Chopstick[(i+1) % 5]);
eat
V(Chopstick[i]);
V(Chopstick[(i+1) % 5]);
think
}
Solution Using Semaphores (cont’d)

Guarantees that no two neighbors will be eating


simultaneously
But, consider the following interleaving:
Philosopher 1 picks chopstick 1
Philosopher 2 picks chopstick 2
Philosopher 3 picks chopstick 3
Philosopher 4 picks chopstick 4
Philosopher 5 picks chopstick 5
Solution Using Critical Regions

enum {Eating, Thinking} state[5];


for(i = 0; i < 5; i++)
state[i] = Thinking;

// Entry(i):
region v when state[(i + 1) % 5] == Thinking
&& state[(i - 1) % 5] == Thinking
do state[i] = Eating;
Solution Using Critical Regions

// Exit(i):
region v when true
do state[i] = Thinking;

Exclusion is guaranteed & no starvation


But: Critical regions are difficult to implement.
Exercise:
Write a starvation-free solution using monitors
The Reader/Writer Problem

Access to data in multithreaded applications:


One or more threads can read a data record
Only one thread can write

Why important?
Transaction systems
File systems
Two Types of Locks on Same Item

Shared: for readers


Exclusive: for writers
Rules:
When the exclusive lock is held, no one else can acquire
access in any form
When the shared lock is held, others can acquire the shared
lock, but no one can acquire the exclusive lock
Two Important Flavors

Reader preferred:
If a new reader comes in & no one is currently writing, it
gets through even if some writer is waiting to get access
Writer preferred:
If a new writer comes in, it gets through as soon as
possible
Example 1

r1 r2 r3 w4 r5 w6 r7 (lock requests by
threads 1 -- 7)
Reader preferred:
r1 r2 r3: go ahead
w4: wait
r5: go ahead
r1
w6: wait r2 r7 w4, w6
r7: go ahead r3 r5
Example 2

r1 r2 r3 w4 r5 w6 r7 (lock requests by
threads 1 -- 7)
Writer preferred:
r1 r2 r3: go ahead
w4: wait
r5: wait
r1
w6: wait r2 w4, w6, r5, r7
r7: wait r3
Solution Using Critical Regions

Read() {
region v when !writing && !waiting do reading++;
// read
region v when true do reading--; }
Solution Using Critical Regions

Write() {
region v when true do waiting++;
region v when !writing && !reading do
{ waiting--; writing = 1 }
// write
region v when true do writing = 0; }
Solution 2
Read() {
region v when true do waiting++;
region v when !writing do {waiting--; reading++;}
// read
region v when true do reading--; }
Solution 2 (cont’d)

Write() {
region v when !reading && !writing && !waiting
do writing = 1;
// write
region v when true do writing = 0; }
Some Important Properties

By definition, there is no solution that can be starvation-free,


why?
There are several variations on the problem definition to avoid
starvation and add more exotic features.
Solution using monitors: see quiz

You might also like