OS Process Synchronization
OS Process Synchronization
Process Synchronization
Background
The Critical-Section Problem
Petersons Solution
Synchronization Hardware
Semaphores
Classic Problems of Synchronization
Monitors
Synchronization Examples
Atomic Transactions
Background
Co-Operating Process: that can affect or be affected by other
processes executing in system
Concurrent access to shared data may result in data inconsistency
Process Synchronization: Ensures coordination among processes and
maintains Data Consistency
Process P1 Process P2
1. X=5
2. X=5+2
1. read(x);
2. x=x+5;
3. Printf( x);
Producer Consumer Problem
There can be two situations:
2. Bounderd Buffer:
1. Limited buffer size
Producer Consumer Problem
Bounderd Buffer:
while (true) {
while (count == 0) // buffer empty
{
; // do nothing
}
nextConsumed = buffer[out];
out = (out + 1) % BUFFER_SIZE;
count- -;
Producer Consumer
count=count-1
count=count+1 4. R2=count
1. R1=count 5. R2=R2-1
2. R1=R1+1 6. Count = R2
3. Count = R1
Process P1 Process P2
1. reads i=10
2. i=i+1 =11
PI got INTERRUPTED
1. P2 reads i=11 from memory
2. i=i+1 = 12
3. Stores i=11 in memory 3. Stores 12 in memory
Critical Section Problem
Section of code or set of operations, in which process
may be changing shared variables, updating common
data.
A process is in the critical section if it executes code that
manipulate shared data and resources.
Each process should seek permission to enter its critical
section Entry Section
Exit Section
Remainder section: Contains remaining code
Structure of a process
Repeat
{
// Entry Section
Critical Section
// Exit Section
Remainder Section
} until false.
Solution to: Critical Section
1. Mutual Exclusion:
It states that if one process is executing in its critical section, then
no other process can execute in its critical section.
2. Bounded Wait:
It states that if a process makes a request to enter its critical
section and before that request is granted, there is a limit on
number of times other processes are allowed to enter that
critical section.
If (shared variable == 1)
P1 can enter to Critical Section
S/w Approaches/Solutions For C.S
Let turn=0
P0 P1
While (1) While (1)
{ {
While(turn !=1);// if true
While(turn !=0);// if true
process will be stuck in the loop
process will be stuck in the loop
CS CS
turn= 1; turn= 0;
} }
S/w Approaches/Solutions For C.S
While(1) While(1)
{ {
Flag[0]=true; Flag[1]=true;
while(Flag[1]); while(Flag[0]);
CS CS
Flag[0]=false; Flag[1]=false;
} }
2nd S/W Approach
The variable turn indicates whose turn it is to enter the critical section.
The flag array is used to indicate if a process is ready to enter the critical
section. flag[i] = true implies that process Pi is ready!
Algorithm for Petersons solution
P0 P1
While(1) While(1)
{ {
Flag[0]=true; Flag[1]=true;
turn=1; turn=0;
while(turn==1 && while(turn==0 &&
flag[1]==true); flag[0]==true);
CS CS
Flag[0]=false; Flag[1]=false;
} }
Mutual exclusion satisfied.
Progress satisfied.
Bounded wait satisfied.
Synchronization Hardware
Atomic = non-interruptable
Either test memory word and set value
Or swap contents of two memory words
Hardware Solution to C.S.
Interrupt Disabling
Repeat
Disable interrupts
C.S
Enable interrupts
Remainder section
Hardware Solution to C.S.
Hardware instructions
1. Machines provide inst. That can read, modify and
store memory word
2. Common inst. are:
1. Test and Set
This inst. Provides action of testing a variable and set
its value
It executes atomically
Test and Set instructions operates on single Boolean
variable.
TestAndndSet Instruction
Definition:
while (true)
{
boolean TestAndSet (boolean *lock) while ( TestAndSet (&lock ));
{
boolean init = lock;
lock= TRUE; // critical section
return init;
} lock = FALSE;
// remainder section
}
Swap Instruction
Definition:
Definition
while (true) {
void Swap (boolean *a, boolean *b) key = TRUE;
{ while ( key == TRUE)
boolean temp = *a; {
*a = *b; Swap (&lock, &key );
*b = temp: }
} // critical section
lock = FALSE;
// remainder section
}
Bounded waiting mutual exclusion with TestAndSet
do
{ waiting[i] = true;
key = true;
while (waiting[i] && key)
key = test_and_set(&lock);
waiting[i] = false;
/* critical section */
j = (i + 1) % n;
while ((j != i) && !waiting[j])
j = (j + 1) % n;
if (j == i)
lock = false;
else waiting[j] = false; /* remainder section */
}
while (true);
Semaphore
Semaphore S integer variable
Two standard operations modify S: wait() and signal()
Originally called P() and V()
Less complicated
Can only be accessed via two indivisible (atomic) operations
wait (S) {
while S <= 0
; // no-op
S--;
}
signal (S) {
S++;
}
We can use semaphore to solve various synchronization
problem.
o Let P1 and P2 are two process
o P1 wants to execute S1 statement. And P2 wants to
execute S2 statement.
o S1 is to be executed before S2
S1;
Signal(synch);
Wait(synch);
S2
Semaphore as General Synchronization Tool
Two operations:
block place the process invoking the operation on the
appropriate waiting queue.
wakeup remove one of processes in the waiting queue
and place it in the ready queue.
Semaphore Implementation with no Busy waiting (Cont.)
Implementation of wait:
wait (S){
value--;
if (value < 0) {
add this process to waiting queue
block(); }
}
Implementation of signal:
Signal (S){
value++;
if (value <= 0) {
remove a process P from the waiting queue
wakeup(P); }
}
Deadlock and Starvation
Bounded-Buffer Problem
Readers and Writers Problem
Dining-Philosophers Problem
Bounded-Buffer Problem
while (true) {
// produce an item
wait (empty);
wait (mutex);
signal (mutex);
signal (full);
}
Bounded Buffer Problem (Cont.)
The structure of the consumer process
while (true) {
wait (full);
wait (mutex);
signal (mutex);
signal (empty);
}
Readers-Writers Problem
Shared Data
Data set
Semaphore mutex initialized to 1.
Semaphore wrt initialized to 1.
Integer readcount initialized to 0.
Readers-Writers Problem (Cont.)
while (true) {
wait (wrt) ;
// writing is performed
signal (wrt) ;
}
Readers-Writers Problem (Cont.)
The structure of a reader process
while (true) {
wait (mutex) ;
readcount ++ ;
if (readcount == 1) wait (wrt) ;
signal (mutex)
// reading is performed
wait (mutex) ;
readcount - - ;
if (readcount == 0) signal (wrt) ;
signal (mutex) ;
}
Dining-Philosophers Problem
Shared data
Bowl of rice (data set)
Semaphore chopstick [5] initialized to 1
Dining-Philosophers Problem (Cont.)
While (true) {
wait ( chopstick[i] );
wait ( chopStick[ (i + 1) % 5] );
// eat
signal ( chopstick[i] );
signal (chopstick[ (i + 1) % 5] );
// think
}
Problems with Semaphores
monitor monitor-name
{
// shared variable declarations
procedure P1 () { . }
procedure Pn () {}
Initialization code ( .) { }
}
}
Schematic view of a Monitor
Condition Variables
condition x, y;
monitor DP
{
enum { THINKING; HUNGRY, EATING) state [5] ;
condition self [5];
initialization_code() {
for (int i = 0; i < 5; i++)
state[i] = THINKING;
}
}
Solution to Dining Philosophers (cont)
dp.pickup (i)
EAT
dp.putdown (i)
Monitor Implementation Using Semaphores
Variables
semaphore mutex; // (initially = 1)
semaphore next; // (initially = 0)
int next-count = 0;
wait(mutex);
body of F;
if (next-count > 0)
signal(next)
else
signal(mutex);
x-count++;
if (next-count > 0)
signal(next);
else
signal(mutex);
wait(x-sem);
x-count--;
Monitor Implementation
if (x-count > 0) {
next-count++;
signal(x-sem);
wait(next);
next-count--;
}
Synchronization Examples
Solaris
Windows XP
Linux
Pthreads
Solaris Synchronization
Linux:
disables interrupts to implement short critical sections
Linux provides:
semaphores
spin locks
Pthreads Synchronization
System Model
Log-based Recovery
Checkpoints
Concurrent Atomic Transactions
System Model
Using the log, system can handle any volatile memory errors
Undo(Ti) restores value of all data updated by Ti
Redo(Ti) sets values of all data in transaction Ti to new values
Undo(Ti) and redo(Ti) must be idempotent
Multiple executions must have the same result as one execution
If system fails, restore state of all updated data via log
If log contains <Ti starts> without <Ti commits>, undo(Ti)
If log contains <Ti starts> and <Ti commits>, redo(Ti)
Checkpoints