I have started learning Critical Section Problem and its various solutions. To explain my question, let me first give a brief background of it.
The general structure for a two Process Solution for Critical Section Problem- Algorithm 1 is:
turn = 0;
do
{
while (turn != 0) ; //if not P0's turn , wait indefinitely
// critical section of Process P0
turn = 1; //after P0 leaves critical section, lets P1 in
//remainder section
} while (1); //loop again
The problem with this Algorithm is that it doesn't support the necessary requirement of Progress. It forces the critical section to be owned in equal turns by P0 -> P1 -> P0 -> P1 -> ...
To get over this problem Algorithm 2 is used where variable turn is replaced by an array flag[]. The general structure of algorithm 2 is:
do
{
flag[0] = T ;
while (flag[1]);//if flag[1] is true wait indefinitely
// critical section of Process P0
flag [0] = F; //P0 indicated it no longer needs to be in critical section
//remainder section
} while (1); //loop again
Here, a process can execute its critical section repeatedly if it needs. (Although this algorithm too doesn't supports progress)
Now my question, why can't we use the variable turn inside the do-while loop in Algorithm 1 in the same way as we use the variable flag[] in ALgorithm 2? Below code will explain what I mean:
For process 0:
do
{
turn = 0;
while (turn != 0) ; //if not P0's turn , wait indefinitely
// critical section of Process P0
turn = 1; //after P0 leaves critical section, lets P1 in
//remainder section
} while (1); //loop again
For process 1:
do
{
turn = 1;
while (turn != 1) ; //if not P0's turn , wait indefinitely
// critical section of Process P0
turn = 0; //after P1 leaves critical section, lets P0 in
//remainder section
} while (1); //loop again
Wouldn't the above code allow a process to repeatedly execute its critical section, if needed and hence solve the problem in Algorithm 1?
I know there is something wrong here or else this solution would have been used generally, don't know just exactly what it is.
The critical section is no longer protected. Among the arbitrary scheduling sequences there is this one (one line = exclusive execution during this time by process X):
process action contents of 'turn' critical section entered (by process)
0 "turn = 1;" 1 no
0 "} while(1);" 1 no
1 "while (turn != 1);" 1 no
1 "// critical section P1" 1 yes (1)
0 "do{" 1 yes (1)
0 "turn = 0;" 0 yes (1)
0 "while (turn != 0);" 0 yes (1)
0 "// critical section P0" 0 collision!
Related
So i'm facing a Problem Understanding Monitor Implementation Using Semaphores , i Understod that Conditions of monitor is used for Synchronization problems not the Critical Section one ,
Variables
semaphore mutex; // (initially = 1)
semaphore next; // (initially = 0)
int next_count = 0;
Each function F will be replaced by
wait(mutex);
...
body of F
...
if (next_count > 0)
signal(next);
else
signal(mutex);
Mutual exclusion within a monitor is ensured
i Can't understand that implementation well . why should i signal another process if it's waiting and not Just signal my self ?! .
and i can't understand the x.wait() and x.signal() codes at all
x.wait:
x_count++;
if (next_count > 0)
signal(next);
else
signal(mutex);
wait(x sem);
x_count--;
x.signal():
if (x_count > 0) {
next_count++;
signal(x_sem);
wait(next);
next_count--;
}
i'm trying to understand this topic i searched so much but it still isn't clear
Considering two processes:
Process 0
do{
flag[0] = TRUE;
turn = 1;
while (flag[1] && turn == 1);
critical section
flag[0] = FALSE;
remainder
}while(1)
Process 1
do{
flag[1] = TRUE;
turn = 0;
while (flag[0] && turn == 0);
critical section
flag[1] = FALSE;
remainder
}while(1)
Where flag[] and turn are shared variables.
Suppose process 0 starts executing first and it stops looping at while. Then process 1 goes and stops as well at while. Then process 0 resumes executing, while condition breaks and it executes its critical section. Fine. My question is how is bounded waiting guaranteed? In this scenario I can't seem to work it out:
Process 0 exits the critical section sets flag[0] = FALSE; but then Process 1 does not resume executing rather Process 0 starts all over again, sets flag[0] = TRUE; and can reenter critical section code. What am I missing?
Process 0 exits the critical section sets flag[0] = FALSE; but then
Process 1 does not resume executing rather Process 0 starts all over
again, sets flag[0] = TRUE;
Yes you are right till here but when Process 0 starts all over again and tries to re-enter critical section , it will execute the following two statements again:
flag[0] = TRUE;
turn = 1;
so turn will be 1 and as we know Process 1 has not yet entered critical section due to which the flag[1] is still true and therefore the loop condition
while (flag[1] && turn == 1);
will be true,This means that process 0 will not be able to enter critical section twice. This satisfies the condition of Bounded Waiting. Also whenever Process 1 will resume its execution the condition
while (flag[0] && turn == 0);
will become false as turn is 1 and it will indeed enter critical section.
initial value of flag is
flag[2] is false
Process P0
do {
flag[0] = true;while (flag[1]) ;
<CS>
flag [0] = false;
<RS>
} while (1);
Process P1
do {
flag[1] = true;while (flag[0]) ;
<CS>
flag [1] = false;
<RS>
} while (1);
i want to know that if both processes run at the same time then isn't progress condition false?
My reason is that it creates a deadlock b/w two processes to get into critical section.I also want to know is mutual exclusion is being fulfilled there?
In the below code how is bounded waiting condition satisfied ,I am unable to get the usage of these statements ,why have they applied the condition j!=i and j=(j+1)%n and then the condition mentioned inside if clause using (j==i),please clarify this ,according to me it should only check for waiting[j] , so as to confirm if any other process is waiting for lock or not ,I am unable to get the idea of working of this algorithm ,please explain it .
while ((j != i) && !waiting[j])
j = (j + 1) % n;
if (j == i)
lock = false;
do {
waiting[i] = true;
while (waiting[i] && 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);
Bounded waiting means no process should wait for a resource for infinite amount of time.
You have n processes, process i is currently executing, when it enters the critical section, it sets its waiting to false.
Now, what happens when process i has finished ?
Process i will look for an index j (process j) that is waiting to run in critical section. In other words, we are looking for a process that is waiting to enter the critical section that is different from the current process that ran in critical section.
if (i==j), then no such process exists, we set lock to false. Otherwise, we set the process that is waiting to run and prevent starvation. And this way you satisfy Bounded Waiting.
This is achieved because you do a circular search, you first check processes
i+1, i+2, .... n, 0, 1, ... ,(i-1)
I am recently studying Peterson's Solution to Critical Section problem.
Let i and j two processes entering critical section,
I am not understanding why we set flag[j] == true in While loop when
its i's turn to enter critical section.
do
{
flag[i] = true;
turn = j;
while(**flag[j] == true** && turn == j);
Critical Section
flag[i] = false;
}
while(true);
while(flag[j] == true && turn == j);
This line says that if the other process is executing its critical section, then the first process should keep on waiting till the second process sets its flag variable(shared variable) to false.
Only after the second process executes its critical section, and sets its flag variable(shared variable) to false, the first process would start executing its critical section.