You are on page 1of 18

06-09-2015

Cooperating processes
Execution of most of the processes relies on
Process Synchronization each other. These processes are called
cooperating processes.
Naveen Aggarwal Cooperating processes communicate with each
other either by
Shared logical address space (threads or LWP) or
Shared files (asynchronously running processes at a
same time in memory)

Naveen Aggarwal Naveen Aggarwal

Producer Consumer Problem Producer Process


Producer tries to produce when buffer is full. while (1) {
Consumer tries to consume when buffer is /* infinite loop till buffer is full*/
empty.
while (buffer==full);
Produce new item and add into buffer;
Increment buffer;
}

Naveen Aggarwal Naveen Aggarwal

1
06-09-2015

Consumer Process Race Condition


while (1) { Assume both consumer and producer are
running concurrently and both are accessing
/* infinite loop till buffer is empty */
the buffer variable with value=x
while (buffer==empty); Producer will make it x+1 & consumer will x-1.
consume new item from buffer; After production of an item and consumption
decrement buffer; of an item the value of var buffer should be x.
} But outcome depends upon who writes last,
If producer then x+1 and
if consumer then x-1.

Naveen Aggarwal Naveen Aggarwal

Avoiding Race Condition Critical Section


Restrict the access of shared variable part of the program where shared memory is
At a time only single process can access it. accessed
How to ensure? All the cooperating processes have critical
section where they execute statement to
access shared memory
Entry Criteria
Exit Criteria

Naveen Aggarwal Naveen Aggarwal

2
06-09-2015

Critical Section Conditions Critical Section Conditions Contd..


Mutual Exclusion: Only one process at a time Bounded waiting: A process requesting to
can enter and execute in critical section. enter critical section should not made to wait
Progress: If no process is executing in critical indefinitely by allowing other processes to
section, then one of the process competing to enter the critical section. So if a process has
enter the critical section, should be allowed. made a request to enter critical section, there
i.e. some progress should always be there. should be bound on the number of other
Finite Stay: A process entered in critical processes being granted to enter critical
section should remain there for finite time section before requesting process gets
only. permission.

Naveen Aggarwal Naveen Aggarwal

Critical Section Conditions Contd.. Critical Section Conditions Contd..


No deadlock or starvation: Processes should Disabling Interrupts:
not be allowed to enter into deadlock by It is not allowed to disable interrupts by a user
waiting for each other to release resources. process before entering the critical section.
Processes should also not to be allowed to wait Even though it seems a good solution that process
indefinitely to enter critical section in critical section should not be interrupted and it
can enable interrupt after coming out of critical
No assumption about CPU: There should not
section.
be any assumption made about the number
But most of operating systems do not want to give
and speed of CPU. the power of disabling interrupts to user processes

Naveen Aggarwal Naveen Aggarwal

3
06-09-2015

Solution 1: Using turn variable


Two Process Solution
while (1) { while (1) {
/* infinite loop till turn*/ /* infinite loop till turn*/
BUSY WAITING SOLUTIONS while (turn!=1); //Entry Criteria while (turn!=0); //Entry Criteria
critical section critical section
turn=0; //Exit Criteria turn=1; //Exit Criteria
non critical section; non critical section;
} }

Naveen Aggarwal

Solution 1: Analysis Solution 2


This solution fulfills the condition of mutual Proposed by Peterson in 1981
exclusion. Entry Conditions
Two problems Either no other process is willing to enter critical
if one process is in non Critical Section when its section.
turn arrives and other in Critical Section is waiting Or it is the turn of process to enter the critical
for its turn. Then requesting process cannot enter section.
the critical section. So condition for progress is not
fulfilled in this solution.
We have to give turn to a process even if it is not
willing to enter the critical section.

Naveen Aggarwal Naveen Aggarwal

4
06-09-2015

Solution 2: Cont… Solution 3:Test Set and Lock (TSL)


/* For Process A, Similar is for Process B */ TSL is standard instruction provided by all processors.
while (1) { which can be used with shared variable lock to access
/* Show Willingness to enter Critical Section */ critical section.
flag[A]=true;
/* Give other process a chance to enter critical section*/
Process can enter the CSif lock is set to zero.
turn=B; It is a H/W instruction so only a single process at a
/* infinite loop if it is B’s turn and B is also willing to enter Critical time can execute it.
Section*/
while (flag[B] && turn==B); Each process before entry execute TSL, if successful, it
critical section sets lock variable to 1 otherwise it remains in loop.
flag[A]=false; After coming out of CS, lock variable has to set zero.
non critical section;
} So it is also a busy waiting solution

Naveen Aggarwal Naveen Aggarwal

Priority Inversion Problem


This problem arises when lower priority
process is in critical region and higher process
which is allocated CPU is waiting for lower
priority process to come out of critical region. SLEEP & WAKEUP SOLUTIONS
But lower priority process would not get CPU
to come out of critical region.

Naveen Aggarwal

5
06-09-2015

Producer process Producer and Consumer


while (1) { Producer Process Consumer Process
while (1) { while (1) {
/* Sleep if buffer is full*/
/* Sleep if buffer is full*/ /* Sleep if buffer is empty
if (buffer==full) Sleep; if (buffer==full) Sleep; */
Produce new item and add into buffer; Produce new item and add if (buffer==empty) Sleep;
into buffer; consume new item from
Increment buffer; Increment buffer; buffer;
Wakeup(Consumer); Wakeup(Consumer); decrement buffer;
} } Wakeup(Producer);
}

Naveen Aggarwal Naveen Aggarwal

Loosing Wake up Call Loosing Wake up Call Cont…


Producer Process Consumer Process Main problem in this method is unconstrained
while (1) { while (1) { buffer variable.
/* Sleep if buffer is full*/ /* Sleep if buffer is empty
It can be understood with following situation.
if (buffer==full) Sleep; */
Produce new item and if (buffer==empty) Consider buffer is empty and Consumer has just
add into buffer; read it.
Sleep;
Increment buffer; But at that instant, scheduler allocates CPU to
Wakeup(Consumer); consume new item from Producer. Now Producer produces an item and
} buffer; increment buffer and issues Wakeup call to
decrement buffer; consumer.
Wakeup(Producer); But Consumer is not logically sleeping so Wakeup
} call gets lost.
Naveen Aggarwal Naveen Aggarwal

6
06-09-2015

Loosing Wake up Call Cont…


When Consumer gets CPU, it has the old value of
buffer and it now issue Sleep call.
As new value of buffer is 1, so Producer will also issue
Sleep call and both Producer and Consumer will sleep SEMAPHORES
forever.
This problem can be sorted out if we do not allow
wakeup call to get lost by storing it in wakeup bit.
But for multi process case we need more number of
bits to store each wakeup calls.

Naveen Aggarwal

Definition (usually misunderstood) What is Semaphore


A semaphore is a synchronization tool used by Single Integer Variable
an operating system to provide synchronization With Following two operations
among concurrently executing sequential P operation (from Dutch probern to test): It is a
processes. wait operation where value of semaphore is
can be implemented using simple binary or decremented if it is not already zero or less than
integer variable zero.
V Operation (from Dutch Verhogen to increment):
It is a signal operation where value of semaphore is
incremented

Naveen Aggarwal Naveen Aggarwal

7
06-09-2015

P / Wait Operation for Binary Semaphore V / Signal Operation for Binary Semaphore

S is initialized to 1 usually /* This is executed after coming out of the Critical


/* This is executed before entering the Critical Section*/ Section*/
Signal (S) {
Wait (S) { /* S is incremented so that other process can enter CS*/
/* Infinite loop if S is less than or equal to zero*/ S++;
while (S<=0); }
/*if S is more than zero then decrements its value so that
no other process enters CS*/
S--;
}

Naveen Aggarwal Naveen Aggarwal

How Semaphore Works Main Points about semaphore


To provide solution for critical section problem, These are busy waiting
Semaphore is initialized to 1, so that first process can
One Semaphore protect one resources.
enter the CS.
All process have to first execute wait operation to Binary Semaphore protect one instance of
show their willingness to enter critical section. resource, For multiple instances, we need
If Semaphore is not 1, i.e. 0, it means there is already counting semaphores.
some process inside CS, so it goes for infinite loop till Also called Spinlock Semaphores.
S becomes equal to 1.
All the processes after coming out of CSnshould raise
the Signal operation of semaphore to increment the
value of semaphore to allow others.

Naveen Aggarwal Naveen Aggarwal

8
06-09-2015

Counting Semaphore Avoiding Busy Wait


Consider that we have 3 printers So we can allow 3
Wait (S) { Signal (S) {
processes to use them simultaneously. Here S.value--; /*decrement value to S.value++;
semaphore is initialized to 3 show willingness*/ /* if value of semaphore is still
if (S.value<0) zero or less than zero, it means
Every process before using resource execute wait { some processes are still waiting
operation i.e. decrements semaphore by 1. /* No resource is free */ in the waiting list. So one of the
Add this process to waiting process from the list needs to
So after 3 processes starts using, semaphore has 0
list; wakeup */
value. Sleep; If (S.value <=0) {
When one process finished using, it executes Signal } Remove process P from
} waiting list;
operation which increments the semaphore. Wakeup(P);}
Now another waiting process can start using the }

printer.
Naveen Aggarwal Naveen Aggarwal

Avoiding Busy Wait Deadlocks due to Semaphores


Semaphore is initialized to total number of Process P1 Process P2
processes. Wait (R1); Wait (R2);
-ve value represents : Number of processes Wait (R2); Deadlock Occurs here Wait (R1);
waiting in queue. Use (R1); Use (R2);
No Busy Waiting but deadlock can happen … …
How? Use(R2); Use (R1);
… …
Signal (R1); Signal (R2);
Signal (R2); Signal (R1);
Naveen Aggarwal Naveen Aggarwal

9
06-09-2015

To solve Problems
# of processes.
# of resources =# of semaphore variables
semaphores should be initialized to number of
PROBLEM SOLVING USING available instances.
SEMAPHORES Define entry and exit criteria for every critical
section i.e. where shared variables are
modified.
For every P operation (wait), there should be
corresponding V operation (signal).

Naveen Aggarwal

Counting semaphore using binary semaphore Wait Operation


We have binary semaphores and we have to Wait(S1);
/* No one is accessing count variable */
implement counting semaphore.
Count--;
we will use two binary semaphores. if (count <0) {
S1 is used to provide mutual exclusion to /* it means other process are using resources */
count variable and Signal (S1); // Release S1
Wait (S2); // Wait for other processes to release
S2 is used for synchronization. S2 can have resources
only 0 or 1 value, so will be incremented only }
when someone is waiting i.e. it is 0. /* if count is greater than zero, it means there are
resources available */
Signal (S1); // Release S1
Naveen Aggarwal Naveen Aggarwal

10
06-09-2015

Signal Operation Producer Consumer using binary semaphore

Wait(S1); /* No one is accessing count variable */ Counting Semaphore ‘emp-buff’ is used to


Count++; keep track of whether buffer is empty or not. It
if (count <=0) is initialized to MAX value to signify that
/* it means some processes are waiting */ initially we have all spaces empty.
Signal (S2);
Counting Semaphore ‘full-buff’ is used to keep
track of whether buffer is full or not. It is
initialized to 0.
else
/* No process is waiting*/ Binary Semaphore ‘sem-buff’ is used to provide
Signal (S1); // Release S1 exclusive access to buffer variable. It is
initialized to 1.
Naveen Aggarwal Naveen Aggarwal

Producer Process Consumer Process


while (1) { while (1) {
/* Check whether buffer is empty or not*/ /* Check whether buffer is full or not*/
P(emp-buff); P(full-buff);
P(sem-buff); //get exclusive access on buffer P(sem-buff); //get exclusive access on buffer
Add item to buffer; remove item from buffer;
V(sem-buff); //Release access of buffer; V(sem-buff); //Release access of buffer;
V(full-buff); //signal full buffer to consumer V(emp-buff); //signal empty buffer to consumer
} }

Naveen Aggarwal Naveen Aggarwal

11
06-09-2015

Reader Writer Problem Writer Process


Semaphore ‘writer’ is used to provide exclusive P(writer);
access to writers. It is initialized to 1. So that Perform writing;
one writer can write. That is there should be no V(writer);
reader and no writer in it.
Semaphore ‘sem_count’ is used to provide
exclusive access to count variable. It is also
initialized to 1

Naveen Aggarwal Naveen Aggarwal

Reader Process Dining Philosopher Problem


P(sem_count); // to exclusively access count variable Consider there are five philosophers who are
if (count==0) //i.e. there is no reader
sitting on a round dining table.
P(writer); //wait if there is writer in it
count++; //else increase count of reader Each philosopher either thinks or eats noodles
V(sem_count); // release count using two chopsticks.
After eating each philosopher put down both
Perform Reading
chopsticks.
P(sem_count); // to exclusively access count variable
How to provide synchronization to dining
Count--; //else decrease count of reader
if (count==0) //i.e. there is no reader philosopher using Semaphores.
V(writer); //Signal if some writer is waiting
V(sem_count); // release count
Naveen Aggarwal Naveen Aggarwal

12
06-09-2015

Dining Philosopher Problem Cont… simple solution for ith philosopher is


while (1) {
1 P1 2 But this simple solution would
lead to deadlock
wait(left); if every philosopher pick its left
P5 P2 wait(right); stick and waiting for right.

Table eat;
5 3
signal (left);
P4 P3 signal(right);
4

If there are N philosophers and each philosopher picks up the its left and right
think;
chopsticks then ith philosopher will pick up chopsticks with numbers
Right as (i)%N and }
Left as (i+1) % N
We represent each chopstick with a semaphore as it should have mutual
exclusive access

Naveen Aggarwal Naveen Aggarwal

Solution using states Philosopher Code


we would use a state variable for each while (1) {
philosopher which maintains the state of acquire(i); // to acquire chopsticks
philosopher as ‘HUNGRY’, ‘EATING’ or’ eat;
THINKING’.
release(i); //to release chopsticks
For mutual exclusive access to this variable, a
semaphore mutex is used. think;
One semaphore p(i) is used for each }
philosopher.

Naveen Aggarwal Naveen Aggarwal

13
06-09-2015

Check Function Acquire function


function check (i) function acquire (i)
{ {
wait(mutex); // to get exclusive access of state
if (state(i)==HUNGRY and state(Left)!=EATING
and state(Right)!=EATING) state(i)=HUNGRY; // announce willingness to eat
/* to check whether philosopher on left and right are
{ eating or not*/
state(i)=EATING; check(i);
signal(p(i)) // Signal philosopher to eat; signal (mutex);
} wait(p(i)); // to keep philosopher wait
} }

Naveen Aggarwal Naveen Aggarwal

Release Function Sleeping barber problem


function release(i) Consider we have a single barber with single
{ barber chair and N waiting chairs.
wait(mutex); // to get exclusive access of state When there is no customer, barber sleeps and
state(i)=THINKING; // state after eating customer wakes him up.
/* to check whether philosopher on left and right When there are customers, barber attends
want to eat or not*/ them one by one.
check(Left); check(right); Customer can wait for his turn if waiting chairs
are empty otherwise customer returns back..
signal (mutex);
}
Naveen Aggarwal Naveen Aggarwal

14
06-09-2015

Semaphore required Customer


while(1) {
Let there are N chairs and count variable is wait (mutex) // to access count variable
used to count the current customers in shop. if (count>= N) { // i.e. customers are more than chairs
signal(mutex); //release count variable
Following semaphores are required for this exit(); // leave shop }

problem. else
count++; //increase count
Semaphore ‘customer’ is used to wait or signal signal (mutex); //release count variable
customers. It is initialized to 0. signal(customer); // to wakeup barber
wait(barber); // if barber is not yet ready
Semaphore ‘barber’ is used to check the readiness Get Haircut;
of barber. It is also initialized to 0
wait(mutex); //to decrease count variable
Semaphore mutex to provide exclusive access to count--;
signal(mutex); //release count variable
count variable. }

Naveen Aggarwal Naveen Aggarwal

Barber High level Constructs


while(1) { To reduce burden on Programmer and avoid
wait(customer); //sleep until customer wakes up programming errors, We have
signal (barber); // tell customer that barber is Critical Region
ready Monitors

Give haircut; These high level constructs provide


encapsulation and abstraction
}
Private data of each process is encapsulated
from each other and only shared data is visible.

Naveen Aggarwal Naveen Aggarwal

15
06-09-2015

Critical Regions Producer Consumer using CR


Shared Variable
Declared as Structure buffer {
“region v when condition C do statements S;” int buf[n];
It means only statement S can access the int count; }
shared variable v and only a single process can Producer Process Consumer Process
enter the region to execute S. region buffer when (count <n) region buffer when (count >0)
{ {
Produce new item and add Consume an item by removing
into buf; from buf;
Increment count; decrement count;
} }

Naveen Aggarwal Naveen Aggarwal

Critical Regions implemented by OS Monitors


All the process want to enter into critical Three components are defined.
regions may have to wait into queues. Declaration and initialization of variables.
Each operating system manages multiple such Operations on shared data.
queues based on the criticality of processes. Synchronization statements (typical wait and signal
These queues are managed using the statements are defined).
semaphores. If a process wants to use monitor, which is
already in use, then it must wait in queue
which is based on FIFO policy.
Queue Managed by Monitors

Naveen Aggarwal Naveen Aggarwal

16
06-09-2015

Monitors Cont… Reader Writer Using Monitors


monitor ReaderWriter {
Condition variables are used to execute int reader_count=0; //initially there is no reader
synchronization operations like wait and signal. Boolean busy=false; //to give first preference to writer
Condition: ReadOK, WriteOK; //condition variables
After each signal operation, one of the
processes from queue is allowed to enter the void readAcquire() {
if (busy) ReadOK.wait; // wait if monitor is busy
monitor. reader_count increment;
Process may have to satisfy certain condition ReadOK.signal;
}
before start using the monitor.
void readRelease() {
reader_count decrement;
if (reader_count is zero) ReadOK.signal;
}
Naveen Aggarwal Naveen Aggarwal

Reader Writer Using Monitors Cont… Monitors Cont…


void writeAcquire() {
if (busy OR reader_count>0) WriteOK.wait;
Monitors do not prevent a process to keep
busy=true; holding a resource or shared variable in
} monitor.
void writeRelease() { Monitors also do not prevent a process to
busy=false; request again and again to use same variable.
// Give preference to writer process
if (writer process waiting in queue)WriteOK.signal;
else ReadOK.signal;
}
}

Naveen Aggarwal Naveen Aggarwal

17
06-09-2015

THANKS

18

You might also like