When we have multiple processes running at the same time (i.e. concurrently) we know that we must protect them from one another but also at the same time we also might want multiple threads to work on a same problem and thus synchronisation is required.
Race Condition
Conflicts that can arose as process / threads share same memory space / variables
We need to avoid this race condition
Race condition when assigning a pid.
Critical Section
When there is shared memory but the mode is in non-shareable
That piece of code where multiple processes / threads access the same shared data
General structure of a typical process
Solutions to Race Condition / Critical Section
Required Criteria to Fulfil
Mutual Exclusion
if one process is executing its critical section then no other co-operative process should be allowed to execute its dependent critical section at same time.
Progress
- If only one process wants to enter, it should be able to.
- If two or more want to enter, one of them should succeed.
- No process in its remainder section can participate in this decision
- Selection should not be postponed indefinitely
- No deadlock
If both process can run individually one after other in any order (firstly P_0 then P_1 or firstly P_1 then P_0) without any preemption in between then we can say progress is there.
Bounded Waiting
if one process(X) is executing its critical section and other cooperative process(Y) is waiting to go in critical section then when X is completed and if again X wants to go in critical section it should be not be allowed as Y is waiting for Critical section for a long time so Y must get chance before X.
Software Solutions
Lock Variables
- We can set a variable as our
FLAG
to enter critical section or not - A Process which enters critical section turns the FLAG to false / true and hence the other processes wait for that flag in order to access the critical section
-
However, Mutual Exclusion might not be followed
- What if both processes check the flag condition at the same time and find it true?
Strict Alteration with One Variable
- Single Variable as a turn
-
It satisfies Mutual Exclusion but Progress is not maintained
- Process P2 cannot run before P1 as the value of
turn = 0
and thus it will busy wait
- Process P2 cannot run before P1 as the value of
Strict Alteration with Array
- An Array of Flags Determining Need to Access
- Satisfies all conditions
- Deadlock can occur if both program first execute their first conditions and the wait for each other
Peterson’s Solution
- We utilise both the turn and flag array of the Strict Alteration
- Peterson solution isn’t practical because it can not solve critical section problem for more than two processes at the same time
Hardware Solutions
Test and Set
We can build a function that provides atomic behaviour for our critical section
-
Mutual Exclusion is there
-
Progress is there
-
Bounded Waiting is not there
- What if the same process keeps going to the critical section in the while loop while there is no context switching in a scenario?
Fetch and Add
- Mutual Exclusion satisfied
- Progress is achieved
- Bounded Wait is also there
Semaphore
- N Process Solution
- Consists of a single Variable that manages the waiting or access to the critical section
Initialised with 1 or N which allows the count of processes that can access the critical section
Consists of Wait Function which makes the process wait according to the value of S
Upon Exiting the value of S is incremented
- Satisfies Mutual Exclusion
- Satisfies Progress
- Does not satisfy Bounded Wait
Mutex
Mutual Exclusion Variable
The semaphore variable that can be owned by one process at a time
Applications
-
Critical Section Problem
-
Deciding Order of Execution
- We can utilise this by using multiple Semaphore Mutexes
-
Managing multiple resources
- Such as printers that would run simultaneously
-
Classical Problems
-
Bounded Buffer Problem
- Producer - Consumer Synchronisation can be achieved
-
Reader-writers Problem
- We can restrict writing when something is being read
-
Dining Philosopher Problem
-