A Process Using Mutual Exclusion:
int me;
while (1) {
/* non critical section code */
enter(me); /* also called entry code */
/* critical section code */
leave(me); /* also called exit code */
}
We assume each process has access to its process ID, which we're calling me in this example. The process can pass its ID into the enter() and leave() functions.
First try: use a lock.
shared int lock = 0;
void enter(int me)
{
while (lock == 1) /* do nothing */;
lock = 1;
}
void leave(int me)
{
lock = 0;
}
Problem: Process 0 can check that the lock is available, and then get preempted. Process 1 can now check the the lock is available, and enter the critical section. While in the critical section, it can be swapped out, and Process 0 restarted. Since Process 0 has already checked the availability of the lock, it can also enter the critical section. This "solution" fails to provide mutual exclusion.
Second try: take turns
shared int turn = 0;
void enter(int me)
{
while (turn != me);
}
void leave(int me)
{
turn = 1 - me;
}
Problem: If process 0 never attempts to enter the critical section, process 1 is never allowed to enter it (and, if 0 has entered once, it can never enter again until 1 endters). This "solution" fails to guarantee progress. Can you convince yourself it does in fact provide mutual exclusion (so it does meet some of the criteria, but not all)?
Third try: Keep track of whether the other guy wants in
shared int flag[2];
void enter(int me)
{
flag[me] = 1;
while (flag[1-me]);
}
void leave(int me)
flag[me] = 0;
}
Problem: Doesn't satisfy the progress condition. Both processes can get stuck in the entry code and wait there forever, in other words "deadlocked".
Fourth and last try:
(Peterson's Algorithm): combine second and third
The basic approach here is that we're going to keep track of both whether the other process wants in, and also whose turn it is. If the other process wants to get in, we'll let it in if it's its turn. But if it doesn't want in, we'll take its place.
shared int flag[2];
shared int turn;
void enter(int me)
{
flag[me] = 1;
turn = 1-me;
while (flag[1-me] && (turn == (1-me)));
}
void leave(int me)
{
flag[me] = 0;
}
This solution meets all of the requirements
No comments:
Post a Comment