0% found this document useful (0 votes)
92 views25 pages

Process Synchronization Continued: Producer/Consumer (Unbounded Buffer) Producer/Consumer (Bounded Buffer)

This document discusses process synchronization and classic synchronization problems. It begins with an overview of semaphores, including busy waiting semaphores and blocking semaphores. It then discusses how semaphores can be used to solve critical section problems and synchronize processes. Several classic synchronization problems are introduced, including the producer-consumer problem for both unbounded and bounded buffers, as well as the dining philosophers problem.

Uploaded by

Hemanth
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
92 views25 pages

Process Synchronization Continued: Producer/Consumer (Unbounded Buffer) Producer/Consumer (Bounded Buffer)

This document discusses process synchronization and classic synchronization problems. It begins with an overview of semaphores, including busy waiting semaphores and blocking semaphores. It then discusses how semaphores can be used to solve critical section problems and synchronize processes. Several classic synchronization problems are introduced, including the producer-consumer problem for both unbounded and bounded buffers, as well as the dining philosophers problem.

Uploaded by

Hemanth
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 25

Process Synchronization

Continued
7.4 Semaphores
7.5 Classic Problems of Synchronization
Producer/Consumer (unbounded buffer)
Producer/Consumer (bounded buffer)
Busy Waiting Semaphores
 The simplest way to S is an integer variable
implement that, apart from
semaphores. initialization, can only
be accessed through 2
 Useful when critical atomic and mutually
sections last for a exclusive operations:
short time, or we have
lots of CPUs.
wait(S):
while S<=0 do ;
 S initialized to positive S--;
value (to allow
someone in at the
beginning). signal(S):
S++;
Using semaphores for solving critical
section problems
 For n processes
 Initialize semaphore Process Pi:
“mutex” to 1 repeat
wait(mutex);
 Then only one process
CS
is allowed into CS
signal(mutex);
(mutual exclusion)
RS
 To allow k processes forever
into CS at a time,
simply initialize mutex
to k
Synchronizing Processes using
Semaphores
 Two processes:  Define a semaphore
“synch”
• P1 and P2
• Initialize synch to 0
 Statement S1 in P1
needs to be
performed before  Put this in P2:
statement S2 in P2 wait(synch);
S2;
 Need to make P2
wait until P1 tells it
it is OK to proceed  And this in in P1:
S1;
signal(synch);
Busy-Waiting Semaphores:
Observations
 When S>0:
• the number of processes that can execute
wait(S) without being blocked = S
 When S=0: one or more processes are
waiting on S
 Semaphore is never negative
 When S becomes >0, the first process that
tests S enters enters its CS
• random selection (a race)
• fails bounded waiting condition
Blocking Semaphores

 In practice, wait and signal are system calls to the


OS
• The OS implements the semaphore.
 To avoid busy waiting:
• when a process has to wait on a semaphore, it will be
put in a blocked queue of processes waiting for this to
happen.
 Queues are normally FIFO. This gives the OS
control on the order processes enter CS.
• There is one queue per semaphore
• just like I/O queues.
Blocking Semaphores:
Implementation
 A semaphore can be seen as a record (structure):

typedef struct {
int count;
struct PCB *queue;
} semaphore;

semaphore S;
 When a process must wait for a semaphore S, it
is blocked and put on the semaphore’s queue
 Signal(S) removes one process from the queue
and moves it to Ready.
Semaphore Operations in OS (atomic)
void wait(semaphore S){
S.count--;
if (S.count<0) {
add this process to S.queue
block this process
}
}
signal(S){
S.count++;
if (S.count<=0) {
move one process P from S.queue
to ready list
}
Negative count indicates number of processes
waiting
Semaphores: Implementation

 wait() and signal() themselves contain


critical sections! How to implement them?
 Notice: they are very short critical
sections.
 Solutions:
• uniprocessor: disable interrupts during these
operations (ie: for a very short period).
 Fails on a multiprocessor machine.
• multiprocessor: use some busy waiting
scheme, such as test-and-set.
 The busy-wait will be short, so it can be
tolerated.
Deadlocks and Semaphores

Process P0: Process P1:

wait(S); wait(Q);
wait(Q); wait(S);
. .
. .
signal(S); signal(Q);
signal(Q); signal(S);

This could function correctly sometimes, but:


What if P0 reaches dotted line, and context switch to P1?
Binary Semaphores
 The semaphores we have studied are
called counting semaphores
 We can also have binary semaphores
• similar to counting semaphores except that
“count” can only be 0 or 1
• simpler to implement on some hardware
 Can still be used in “counting” situations
• need to add additional counting variables
protected by binary semaphores.
• See example in section 7.4.4
Binary Semaphores
waitB(S):
if (S.value == 1) {
S.value = 0;
} else {
place this process in S.queue
block this process
}

signalB(S):
if (S.queue is empty) {
S.value = 1;
} else {
move a process P from S.queue
to ready list
}
Some Classic Synchronization
Problems
 Bounded Buffer (Producer/Consumer)

 Dining Philosophers Problem

 Readers-Writers Problem
The Producer/Consumer Problem
 A producer process produces information that is
consumed by a consumer process
• Example: Implementation of pipes on Unix systems

 We need a buffer to hold items that are produced


and eventually consumed
 and a way for the producer and the consumer of
the items to coordinate their access to the buffer
 A common paradigm for cooperating processes
Producer/Consumer: Unbounded
Buffer
 We look first at an unbounded buffer consisting
of a linear array of elements
 in points to the next item to be produced
 out points to the next item to be consumed
 Number of elements = (in-out)
Unbounded Buffer: Observations
 If only the producer alters the pointer in and only
the consumer alters out, and only the producer
writes to the buffer itself, mutual exclusion in this
simple case may not be an issue if the code is
written carefully
 The producer write whenever it wants, but
 ..the consumer must check to make sure the
buffer is not “empty” (in==out)?
 So the consumer may have to busy-wait, waiting
for the producer to provide at least one item
Pitfalls with Simple Solution

 Producer basically does


b[in] = item; in++;
 and consumer does
while (out >= in) ; /* Wait… */
item = b[out]; out++;
 What could happen if the producer
adjusted “in” before it put the data in?
in++; b[in-1] = produced_item;
Producer/Consumer: Unbounded
Buffer Semaphore Solution
 Let’s make it “clean”
• declare the buffer and its pointers to be critical data
• And protect them in a critical section

 Use a semaphore “mutex” to perform mutual


exclusion on the buffer and pointers

 Use another semaphore “number” to synchronize


producer and consumer on the number (= in - out)
of items in the buffer
• an item can be consumed only after it has been created
• (The semaphore value itself is the item count)
Producer/Consumer: Unbounded
Buffer
 The producer is free to add an item into the
buffer at any time: it performs wait(mutex)
before appending and signal(mutex)
afterwards to prevent access by the
consumer
 It also performs signal(number) after each
append to increment number
 The consumer must first do wait(number) to
see if there is an item to consume and then
use wait(mutex) / signal(mutex) to access the
buffer
Solution of Producer/Consumer:
Unbounded Buffer
Initialization:
mutex.count:=1; //mutual exclusion
number.count:=0; //number of items
in:=out:=0; //indexes to buffer

append(item): Producer: Consumer:


b[in]:=item; repeat repeat
in++; produce item; wait(number);
wait(mutex); wait(mutex);
take(): append(item); item:=take();
item:=b[out]; signal(mutex); signal(mutex);
out++; signal(number); consume item;
return item; forever forever
critical sections
Producer/Consumer: Unbounded
Buffer
 Remarks:
• Putting signal(number) inside the CS of the producer
(instead of outside) has no useful effect since the
consumer must always wait for both semaphores
before proceeding
• The consumer must perform wait(number) before
wait(signal), otherwise deadlock occurs if consumer
enters CS while the buffer is empty. Why?
 because it would lock the producer out!
• Disaster if you forget to do a signal after a wait.
 So using semaphores still has pitfalls...
 Now let’s look at what happens if the buffer is
bounded
Producer/Consumer: Circular Buffer of
Size k (Bounded Buffer)

 can consume only when number of (consumable)


items is at least 1 (now: number != in-out)
 can produce only when number of empty spaces
is at least 1
Producer/Consumer: Bounded Buffer

 Again:
• Use a semaphore “mutex” for mutual exclusion
on buffer access
• and a semaphore “full” to synchronize producer
and consumer on the number of consumable
items (full spaces)
 But we have to add:
• a semaphore “empty” to synchronize producer
and consumer on the number of empty spaces
Producer/Consumer:
Bounded Buffer (Solution)
Initialization: mutex.count:=1; //mutual excl.
full.count:=0; //full spaces
empty.count:=k; //empty spaces

append(item): Producer: Consumer:


b[in]:=item; repeat repeat
in=(in+1)mod k; produce item; wait(full);
wait(empty); wait(mutex);
take(): wait(mutex); item:=take();
item:=b[out]; append(item); signal(mutex);
out=(out+1)mod k; signal(mutex); signal(empty);
return item; signal(full); consume(item);
forever forever
critical sections
The Dining Philosophers Problem
( read 7.5.3 for next class)

 5 philosophers who only


eat and think
 each needs to use 2
forks for eating
 but we have only 5 forks!
 A classical
synchronization problem
 Illustrates the difficulty
of allocating resources
among process without
deadlock and starvation

You might also like