Oslecture6-7 (Copy)
Oslecture6-7 (Copy)
Outline
• Cooperating Processes
• Inter - process Communication
• The Bounded Buffer Producer-Consumer
Problem
• The Critical Section Problem
• Synchronization Hardware
• Semaphores
• Classical Problems of Synchronization
• Monitors
Cooperating Processes
• Concurrent Processes can be
- Independent process:
Any process that does not share any
data with any other process.
- Cooperating process:
Any process that shares data with other
processes.
Contd..
• Advantages of process cooperation:
1. Information Sharing
- Several user may be interested in the
same piece of information.
- For eg. Shared files
- Provide an environment to allow
concurrent access.
Contd..
2. Computation speedup
- If we want a particular task to run faster, then break it
into subtask.
- Each task will be executing in parallel with others.
3.Modularity
- Construct the system in modular fashion.
- Divide the system functions into separate process.
Contd..
4.Convenience
- An individual user may have many task
to work on at one time.
- For instance, a user may be editing,
printing etc.
Producer-Consumer Problem
• Paradigm for cooperating processes;
– producer process produces information that is
consumed by a consumer process.
• We need buffer of items that can be filled
by producer and emptied by consumer.
– Unbounded-buffer places no practical limit on the size of
the buffer. Consumer may wait, producer never waits.
– Bounded-buffer assumes that there is a fixed buffer size.
Consumer waits for new item, producer waits if buffer is
full.
– Producer and Consumer must synchronize.
Producer-Consumer Problem
Bounded-buffer - Shared
Memory Solution
• Shared data
var n;
type item = ….;
var buffer: array[0..n-1] of item;
in, out: 0..n-1;
in :=0; out:= 0; /* shared buffer = circular array */
/* Buffer empty if in == out */
/* Buffer full if (in+1) mod n == out */
/* no-op means ‘do nothing’ */
Bounded Buffer - Shared
Memory Solution
• Producer process - creates filled buffers
repeat
…
produce an item in nextp
…
while in+1 mod n = out do no-op;
buffer[in] := nextp;
in := in+1 mod n;
until false;
Bounded Buffer - Shared
Memory Solution
• Consumer process - Empties filled buffers
repeat
while in = out do no-op;
nextc := buffer[out] ;
out:= out+1 mod n;
…
consume the next item in nextc
…
until false
Bounded Buffer
• A solution that uses all N buffers is not that simple.
• Modify producer-consumer code by adding a variable
counter, initialized to 0, incremented each time a new
item is added to the buffer & decremented every time to
remove one item from the buffer.
• Shared data
type item = ….;
var buffer: array[0..n-1] of item;
in, out: 0..n-1;
counter: 0..n;
in, out, counter := 0;
Bounded Buffer
• Producer process - creates filled buffers
repeat
…
produce an item in nextp
…
while counter = n do no-op;
buffer[in] := nextp;
in := in+1 mod n;
counter := counter+1;
until false;
Bounded Buffer
• Consumer process - Empties filled buffers
repeat
while counter = 0 do no-op;
nextc := buffer[out] ;
out:= out+1 mod n;
counter := counter - 1;
…
consume the next item in nextc
…
until false;
• The statements
counter := counter + 1;
counter := counter - 1;
must be executed atomically.
Contd..
• The value of the variable counter is 5, the producer & consumer executes
statements concurrently
• T0: producer execute register1:=counter {register =5}
• T1: producer execute register1:=register1+1{register =6}
• T2: consumer execute register2:=counter {register =5}
• T3: consumer execute register2:=register2-1{register =4}
• T4: producer execute counter:=register1{counter =6}
• T5: consumer execute counter:=register2{counter =4}
• The value of the variable counter may be 4,5 or 6 but the only correct result
is counter = 5 which is generated correctly if producer & consumer execute
separately.
• We would arrive at this incorrect outcomes because we
allowed both processes to manipulate counter variable
concurrently.
Race Condition
• Race condition: The situation where
several processes access and manipulate
shared data concurrently. The final value
of the shared data depends upon which
process finishes last.
How to avoid Race Condition?
• To avoid race condition, we need to ensure that
only one process at a time can manipulate the
variable.
• For this we require some form of
synchronization of the processes.
• The problem of process synchronization arises
from the need to share resources. This sharing
requires co-ordination and co- operation to
ensure correct operation.
Interprocess Communication
(IPC)
• Mechanism for processes to communicate and
synchronize their actions.
– Via shared memory
– Via Messaging system - processes communicate without
resorting to shared variables.
• Scrambled Messages
– Message arrives from sender P to receiver Q, but
information in message is corrupted due to noise in
communication channel.
– Solution
» need error detection mechanism, e.g. CHECKSUM
» need error correction mechanism, e.g.
retransmission
Background
• Concurrent access to shared data may
result in data inconsistency.
• Maintaining data consistency requires
mechanisms to ensure the orderly
execution of cooperating processes.
• Shared memory solution to the bounded-
buffer problem allows at most (n-1) items
in the buffer at the same time.
The Critical-Section Problem
• Consider a system consisting of N processes
{P0,P1,... Pn-1}
– Structure of process Pi ---- Each process has a code segment,
called the critical section, in which the shared data is accessed.
repeat
entry section /* enter critical section */
critical section /* access shared variables */
exit section /* leave critical section */
remainder section /* do other work */
until false
• Problem
– Ensure that when one process is executing in its critical section,
no other process is allowed to execute in its critical section.
Types of Solution
• Software solutions
-Algorithms who’s correctness does not rely on any other
assumptions
• Hardware solutions
- Rely on some special machine instructions.
• Operation system solutions
- Provide some functions and data structure to the
programmer.
Mutual Exclusion: Software approach
.
Contd..
• Each process may examine the other’s flag but may
not alter it
flag[0] --- for 0 process
flag[1] --- for 1 process
• If a process fails inside its critical section or after
setting its flag to true just before entering its critical
section, then other process permanently blocked.
• No guarantee of mutual exclusion.
Contd..
• Eg. Consider following sequence:
1. P0 executes the while statement & finds flag[1] set to
false
2. P1 executes the while statement & finds flag[0] set to
false.
3. P0 sets flag[0] true & enter critical section.
4. P1 sets flag[1] true & enter critical section.
• Incorrect
Contd..
• Third Attempt //process 1
//process 0// .
.
.
. Flag[1] = true;
Flag[0] = true; (While (flag[0]));
While (flag[1]); // critical section
// critical section Flag[1] = false;
Flag[0] = false;
Contd..
• Interchange of two statements of second attempt.
• If one process fails inside its critical section then
other is blocked.
• If one process fails outside its critical section then
other not blocked.
• Guarantee of mutual exclusion.
• Eg. Po set flag[0] true then p1 can not enter in its
critical section.
Contd..
• If P1 is already in its critical section then P0
blocked by while statement until P1 has left its
critical section.
• Deadlock can be there as,
-Both processes set their flag true before
executing while statement, then each will think
that other is in its critical section , cause
deadlock.
Contd..
• Fourth Attempt
//process 1
//process 0// .
. .
. Flag[1] = true;
Flag[0] = true; While (flag[0])
While (flag[1]) {
{ Flag[1]= false;
Flag[0]= false; //delay
//delay Flag[1] = true;
Flag[0] = true; }
} // critical section
// critical section Flag[1] = false;
Flag[0] = false;
Contd..
• Deadlock occurs because each process can insist on
its right to enter its critical section in previous
attempt.
• Each process sets its flag to indicate its desire to enter
its critical section but is prepared to reset.
• Mutual exclusion is guranteed, but livelock problem
• Consider following sequences
1. P0 sets flag[0] to true
2. P1 sets flag[1] to true
Contd..
3. P0 checks flag[1]
4. P1 checks flag[0]
5. P0 sets flag[0] to false
6. P1 sets flag[1] to false
7. P0 sets flag[0] to true
8. P1 sets flag[1] to true
• This sequence could be extend indefinitely and neither process
could enter its critical section.
• But no deadlock it is livelock.
• Any alteration in relative speed of two process will break this
cycle
• Still not satisfactory.
Correct Solution
• Must impose an order on the activities of
the two processes.
• Use variable turn from first attempt.
• When turn = 0 & flag[1] false , p0 can
enter in its critical section.
Contd..
Boolean flag[2]; Flag[0]= true;
int turn; }
Void p0() //critical section
{
Turn = 1;
While(true)
{ Flag[0] = false;
Flag[0] = true; //remainder
While(flag[1]) }
If(turn = = 1) }
{
Flag[0]=false;
While(turn = = 1)
//do nothing
Contd..
Void p1() Turn = 0;
{ Flag[1]= false;
While(true) //remainder
{
}
Flag[1] = true;
While(flag[0]) }
If(turn = = 0) Void main( )
{ {
Flag[1]=false; flag[0] = false;
While(turn = = 0)
Flag[1] = false;
//do nothing
Flag[1] = true; Turn = 1;
} Parbegin (p0,p1);
//critical section
Peterson’s Algorithm
• Dekker’s approach is difficult & correctness is tricky to
prove.
• Global variable flag indicates the position of each process
w.r.to mutual exclusion & turn resolves conflicts.
• In p0, if flag[0] true then p1 can not enter critical section
• If p1 is already in critical section then p0 blocked from
entering its critical section.
• If p0 is blocked in while loop shows flag[1] true and
turn = 1
• P0 can enter when either flag[1] becomes 0 or turn = 0;
Contd..
• 3 cases
1.p1 has no interest in critical section because it
indicates flag[1] = false
2. p1 is waiting for its critical section because if
turn =1, p1 is able to enter its critical section.
3.P1 is monopolizing , impossible.
Contd..
Void p1 ( )
Boolean flag[2]; {
int turn; While(true)
{
Void p0 ( )
Flag[1] = true;
{
turn = 0;
While(true)
While(flag[0]&& turn = = 0)
{ //do nothing
Flag[0] = true; // critical section
Turn = 1; Flag[1]=false;
While(flag[1]&& turn = = 1) //remainder
//do nothing }}
// critical section Void main ()
Flag[0]=false; {
Flag[0]= false;
//remainder
Flag[1] = false;
}}
Perbegin(p0,p1)
}
Synchronization Mechanisms
• Disable Interrupts
• Test-and-Set instruction
• Exchange Instruction
• In a uni-processor environment, we could
disallow interrupts to occur while a shared
variable is being modified.
• This way, we could be sure that the current
sequence of instructions would execute without
any preemption.
Synchronization hardware
Mutual exclusion: hardware solution
In the uni-processor system, it is sufficient to prevent a
process from being interrupted.
While (true) {
/*disable interrupts*/
/*critical section*/
/*enable interrupts*/
/*remainder*/
Since CS can not be interrupted ME is guaranteed.
The efficiency decrease.
It can not work in multi-processor environments
- more than one process is executing at a time.
Hardware Solutions for
Synchronization
• Mutual exclusion solutions presented depend on
memory hardware having read/write cycle.
– If multiple reads/writes could occur to the same memory
location at the same time, this would not work.
– Processors with caches but no cache coherency cannot
use the solutions
• In general, it is impossible to build mutual
exclusion without a primitive that provides some
form of mutual exclusion.
• How can this be done in the hardware???
Synchronization Hardware
• Test and set Instruction
• Defination
boolean testset (int i)
{
if (i = = 0)
{
i=1;
return true;
}
else
return false;
}
Contd..
– Process Pi
repeat
wait(mutex);
critical section
signal (mutex);
remainder section
until false
Implementation of Semaphores
• The main disadvantage of the previous mutual
exclusion solutions is that they all require busy
waiting. While a process is in its critical
section, any other process that tries to enter
must loop continuously in the entry code. Busy
waiting wastes CPU cycles.
• To overcome busy waiting, we can modify the
definition of the wait and signal semaphore
operations.
Cont..
• When a process executes the wait operation
and finds that the semaphore value is not
positive, it must wait. However, rather than busy
waiting,the process can block itself.
• The block operation places the process into a
waiting queue associated with the
semaphore,and the state of the process is
switched to the waiting state.Then the control is
transferred to the scheduler which selects
another process to execute.
Cont..
• A process that is blocked should be
restarted when some other process
executes a signal operation.
• The process is started by a wakeup
operation,which changes its state from
waiting to ready.
Semaphore Implementation
• Define a semaphore as a record
type semaphore = record
value: integer;
L: list of processes;
end;
• Assume two simple operations
• block suspends the process that invokes it.
• wakeup(P) resumes the execution of a blocked
process P.
Semaphore
Implementation(cont.)
– Semaphore operations are now defined as
wait (S): S.value := S.value -1;
if S.value < 0
then begin
add this process to S.L;
block;
end;
– Philosopher i :
repeat
wait (chopstick[i]);
wait (chopstick[i-1 mod 5]);
…
eat
...
signal (chopstick[i]);
signal (chopstick[i+1 mod 5]);
…
think
…
until false;
Critical Regions
• High-level synchronization construct
• A shared variable v of type T is declared
as:
var v: shared T
• Variable v is accessed only inside
statement
region v when B do S
where B is a boolean expression.
While statement S is being executed, no other
process can access variable v.
Critical Regions (cont.)
• Regions referring to the same shared
variable exclude each other in time.
• When a process tries to execute the region
statement, the Boolean expression B is
evaluated.
• If B is true, statement S is executed.
• If it is false, the process is delayed until B becomes
true and no other process is in the region
associated with v.
Example - Bounded Buffer
– Shared variables
var buffer: shared record
pool:array[0..n-1] of item;
count,in,out: integer;
end;
– Producer Process inserts nextp into the
shared buffer
region buffer when count < n
do begin
pool[in] := nextp;
in := in+1 mod n;
count := count + 1;
end;
Bounded Buffer Example
– Consumer Process removes an item from the
shared buffer and puts it in nextc
region buffer when count > 0
do begin
nextc := pool[out];
out := out+1 mod n;
count := count -1;
end;
Implementing Regions
• Region x when B do S
var mutex, first-delay, second-delay: semaphore;
first-count, second-count: integer;
• Mutually exclusive access to the critical
section is provided by mutex.
If a process cannot enter the critical section because
the Boolean expression B is false,
it initially waits on the first-delay semaphore;
moved to the second-delay semaphore before it is allowed
to reevaluate B.
Implementation
• Keep track of the number of processes
waiting on first-delay and second-delay,
with first-count and second-count
respectively.
• The algorithm assumes a FIFO ordering in
the queueing of processes for a
semaphore.
• For an arbitrary queueing discipline, a
more complicated implementation is
required.
Implementing Regions
wait(mutex);
while not B
do begin first-count := first-count +1;
if second-count > 0
then signal (second-delay);
else signal (mutex);
wait(first-delay);
first-count := first-count -1;
second-count := second-count + 1;
if first-count > 0 then signal (first-delay)
else signal (second-delay);
wait(second-delay);
second-count := second-count -1;
end;
if first-count > 0 then signal (first-delay);
else if second-count > 0
then signal (second-delay);
else signal (mutex);
Monitors
• High-level synchronization construct that allows
the safe sharing of an abstract data type among
concurrent processes.
type monitor-name = monitor
variable declarations
procedure entry P1 :(…);
begin … end;
Cont..
procedure entry P2(…);
begin … end;
procedure entry Pn (…);
begin…end;
begin
initialization code
end
Cont…
• To allow a process to wait within the monitor, a
condition variable must be declared, as
var x, y: condition
• Condition variable can only be used with the
operations wait and signal.
• The operation
x.wait;
means that the process invoking this opeation
is suspended until another process invokes
Cont..
x.signal;
• The x.signal operation resumes exactly one
suspended process. If no process is
suspended, then the signal operation has no
effect.
Schematic
Schematic viCewC
viCewC of
of aa monitor
monitor
Operating System
Concepts
Monitor
Monitor with
with condition
condition variables
variables
Operating System
Concepts
Cont..
type dining-philosophers = monitor
var state : array [0..4] of :(thinking, hungry, eating);
var self : array [0..4] of condition;
procedure entry pickup (i: 0..4);
begin
state[i] := hungry,
test (i);
if state[i] eating then self[i], wait,
end;
Cont..
procedure entry putdown (i: 0..4);
begin
state[i] := thinking;
test (i+4 mod 5);
test (i+1 mod 5);
end;
Dining
Dining PhiloCsophers
PhiloCsophers (Cont.)
(Cont.)
Variables
var mutex: semaphore (init = 1)
next: semaphore (init = 0)
next-count: integer (init = 0)
Each external procedure F will be replaced by
wait(mutex);
…
body of F;
…
Operating System
Concepts
if next-count > 0
then signal(next)
if next-count >0
then signal(next)
else signal(mutex);else signal(mutex);
Mutual exclusion within a monitor is
Mutual exclusion
ensured. within a monitor is
ensured.
Monitor
Monitor Implementation
Implementation (Cont.)
(Cont.)
x-count := x-count + 1;
if next-count >0
then signal(next)
else signal(mutex);
wait(x-sem);
x-count := x-count – 1;
Operating System
Concepts
Cont..
The operation x.signal can be implemented as:
if x-count > 0
then begin
next-count := next-count + 1;
signal(x-sem);
wait(next);
next-count := next-count – 1;
end;
Cont..
Conditional-wait construct: x.wait(c);
c – integer expression evaluated when the wait
opertion is executed.
value of c (priority number) stored with the
name of the process that is suspended.
when x.signal is executed, process with
smallest associated priority number is
resumed next.
Cont…
• Check two conditions to establish
correctness of system:
• User processes must always make their calls
on the monitor in a correct sequence.
• Must ensure that an uncooperative process
does not ignore the mutual-exclusion
gateway provided by the monitor, and try to
access the shared resource directly, without
using the access protocols.