OS-Module 3.1
OS-Module 3.1
1
PROCESS SYNCHRONIZATION
Producer – Consumer Problem
There is a Buffer with some number of slots.
One item can be stored in each slot of the buffer.
In and out are pointers to the buffer.
Count is a variable which indicates the number of items in the buffer.
Producer is the process which inserts items into the buffer.
In points to the next free slot of buffer into which the producer process inserts the next item.
In pointer is moved to the next position after inserting an item into the buffer.
Count is incremented by 1 after inserting an item into the buffer.
Consumer is the process which removes items from the buffer.
Out points to the slot from which the consumer process removes the item.
Out pointer is moved to the next position after removing an item from the buffer.
Count is decremented by 1 after removing an item from the buffer.
2
Producer Process Consumer Process
The code of producer process is: The code of consumer process is:
while (true) while(true)
{ {
while (count == buffer_size) while (count == 0)
; ;
Buffer[in] = item; item = Buffer[out];
in = (in + 1) % buffer_size; out = (out+1) % buffer_size;
count = count + 1; count = count -1;
} }
3
Producer Process Consumer Process
The code of producer process is: The code of consumer process is:
while (true) while(true)
{ {
P1: while (count == buffer_size) C1: while (count == 0)
P2: ; C2: ;
P3: Buffer[in] = item; C3: item = Buffer[out];
P4: in = (in + 1) % buffer_size; C4: out = (out+1) % buffer_size;
P5: register1 = count; C5: register2 = count;
P6: register1 = register1 + 1; C6: register2 = register2 - 1;
P7: count = register1; C7: count = register2;
} }
Serial Execution of processes
Processes are executed one after another.
CPU is switched to next process only after completion of the currently running process.
N number of processes can be serially executed in N! number of ways.
For example, two processes p1 and p2 can be executed serially in two ways:
1) p1, p2 2) p2, p1
Three processes p1, p2 and p3 can be executed serially in six ways:
1) p1, p2, p3 2) p1, p3, p2 3) p2, p1, p3 4) p2, p3, p1 5) p3, p1, p2 6) p3, p2, p1
5
Independent processes
Processes running in the computer system are said to be independent processes if they are not exchanging or sharing any
data.
Cooperating processes
Processes running in the computer system are said to be cooperating processes if they are exchanging or sharing any data.
Correct output is generated when the independent processes are executed either serially or concurrently.
Correct output is generated when the cooperating processes are executed serially.
7
Another example concurrent execution of producer & consumer processes that leads to wrong result is:
P1, P2, P3, P4, P5, P6, C1, C2, C3, C4, C5, C6, C7, P7.
8
Race condition
Race condition is getting different outputs for different concurrent executions of cooperating processes.
Ex: What are the different values that A and B get after the execution of the processes P1, P2 concurrently?
Initial values of A and B are 6 and 4 respectively.
9
Concurrent execution sequence1: I1, I2, I11, I12
A=6-4=2
B=4+2=6
A=2+1=3
B=6-1=5
A=3, B=5 Process P1: Process P2:
register1 = count;
register1 = register1 + 1;
count = register1;
register2 = count;
register2 = register2 - 1;
count = register2;
Critical Section Problem
When two or more cooperating processes are executing concurrently, then at a time only one process should execute the
statements in its critical section.
(or)
When one process is already executing the statements in its critical section, no other process is allowed to execute the
statements in its critical section.
(or)
No two processes are allowed to execute the statements in their critical section at the same time.
When the execution of cooperating processes is restricted in this way then the correct output is generated even if the
cooperating processes are executed concurrently.
Each process must request permission to start the execution of statements in its critical section.
The critical section may be followed by an exit section which allows the other process to start the execution of
statements in its critical section.
Entry Section
Critical Section
Exit Section
.
.
}
Solutions for Critical Section Problem (or) Solutions for Implementing Mutual Exclusion
Mutual Exclusion
No two processes should execute the statements in their critical section at the same time.
Progress
At any time, at least one process should be in the running state or active. No deadlock should occur.
Bounded waiting
All processes should be given equal chance to execute the statements in their critical sections.
17
Peterson’s Solution
It is applicable to two processes only.
o boolean flag[2];
turn variable indicates whose turn it is to execute the statements in its critical section.
turn=1 - indicates that the 1st process (producer process) can execute the statements in its critical section.
turn=2 - indicates that the 2nd process (consumer process) can execute the statements in its critical section.
flag indicates whether a process is ready to execute the statements in its critical section.
flag[1]=true - indicates that the 1st process (producer process) is ready to execute the statements in its critical section.
flag[2]=true - indicates that the 2nd process (consumer process) is ready to execute the statements in its critical section.
18
The following procedure is used to solve the critical section problem:
When the 1st process (producer process) wants to execute the statements in its critical section then the 1 st process (producer
process) sets flag[1] to true.
If the 2nd process (consumer process) is also ready to execute the statements in its critical section, then the 1 st process
(producer process) allows the 2nd process (consumer process) to execute the statements in its critical section by setting the
turn value to 2.
The 1st process (producer process) waits until the 2nd process (consumer process) completes the execution of statements in
its critical section.
Then the 1st process (producer process) starts executing the statements in its critical section.
The 1st process (producer process) sets flag[1] to false after completing the execution of statements in its critical section.
Same procedure is followed by the 2nd process (consumer process) when it wants to execute the statements in its critical
section.
19
Peterson’s solution to the critical section problem of producer-consumer is as follows:
flag[1]=true; flag[2]=true;
Entry turn=2; Entry turn=1;
Section while(flag[2]==true && turn==2)
Section while(flag[1]==true && turn==1)
;
;
register1 = count;
register2 = count;
register1 = register1 + 1; Critical Section
register2 = register2 - 1; Critical Section
count = register1;
count = register2;
Exit flag[1]=false;
Section Exit flag[2]=false;
} Section
Hardware Solution
boolean lock;
When a process wants to execute the statements in its critical section, the process checks the value of lock variable.
If the value of lock variable is true, then the process is not allowed to execute the statements in its critical section.
If the value of lock variable is false, then the process is allowed to execute the statements in its critical section.
Before executing the statements in the critical section, the process must set the value of lock variable to true.
After executing the statements in the critical section, the process must set the value of lock variable to false.
21
while (true)
{
.
.
Acquire lock;
Critical Section
Release lock;
.
.
}
Test_and_Set()
‘Test_and_Set’ is a hardware instruction which performs operations on the ‘lock’ variable to solve the critical section
problem.
During the execution of Test_and_Set(), the CPU is not switched to any other process.
‘Swap’ is another hardware instruction which is used to solve the critical section problem.
25
The solution to critical section problem of producer-consumer is
1) Binary semaphore
2) Counting semaphore
Binary semaphore is also called as ‘mutex’ variable as binary semaphore is used to implement mutual exclusion.
Counting semaphore is used to provide synchronous access to a resource when the resource is requested by a number of
processes at a time.
Initial value of counting semaphore is equal to the number of instances of the resource.
A queue is associated with each semaphore variable.
1) wait()
2) signal()
wait(s)
{
s=s-1;
if(s<0)
{
Suspend the execution of the process which has invoked the wait() operation;
Insert that process in the queue associated with the semaphore variable s;
}
}
The definition of signal() operation is:
signal(s)
{
s=s+1;
if(s<=0)
{
remove a process from the queue associated with the semaphore variable s;
restart the execution of that removed process;
}
}
To solve the critical section problem, a process should invoke wait() operation on the semaphore variable before starting the
execution of statements in its critical section and should invoke signal() operation after executing the statements in its critical
section.
Readers-Writers Problem
Some processes named ‘Readers’ only read data from the database.
At a time, any number of Readers can read data from the database without any conflict.
But, when a Writer is writing data to the database then other Writers and Readers are not allowed to access the database.
read_count variable keeps track of how many Readers are currently reading from the database.
rw_mutex is used by both Readers and Writers to synchronously access the database.
while(true)
{
wait(rw_mutex);
signal(rw_mutex);
}
The code of a Reader process is:
while(true)
{
wait(mutex);
read_count = read_count + 1;
if(read_count == 1)
wait(rw_mutex);
signal(mutex);
wait(mutex);
read_count = read_count - 1;
if(read_count == 0)
signal(rw_mutex);
signal(mutex);
}
Dining Philosopher’s Problem
The philosophers share a circular table surrounded by five chairs, each belonging to one philosopher.
In the center of the table is a bowl of rice, and the table is laid with five single chopsticks as shown in the diagram:
When a philosopher feels hungry then the philosopher tries to pick up the two chopsticks that are closest to him.
When a hungry philosopher has both chopsticks at the same time, he eats without releasing the chopsticks.
When he is finished eating, he puts down both chopsticks and starts thinking again.
semaphore chopstick[5];
A philosopher releases his chopsticks by executing the signal() operation on the appropriate semaphores.
The structure of philosopher i is:
while (true)
{
wait(chopstick[i]);
wait(chopstick[(i+1) % 5]);
signal(chopstick[i]);
signal(chopstick[(i+1) % 5]);