Frequently used methods:
Locking a resource is a common technique to ensure the resource is accessed by only one program or chunk of code
At a time.
Algorithm:
Waiter Solution
Introduce a waiter philosophers must ask his permission before taking up any forks. Because the waiter is aware
Which forks are in use, he is able to arbitrate and prevent deadlock.
// The Key to this method is to introduce a global monitoring variable, which can easily complete monitoring allocation.
Resource hierarchy solution
Another simple solution is achieved by assigning a partial order, or hierarchy, to the resources (the forks, in
This case), and establishing the Convention that all resources will be requested in order, and released in reverse
Order, and that no two resources unrelated by order will ever be used by a single unit of work at the same time.
This is often the most practical solution for real world computer science problems; by assigning a constant
Hierarchy of locks, and by enforcing the ordering of obtaining the locks this problem can be avoided.
// The Key to this solution is to introduce the partial order relationship, and many things will become simple afterwards.
Chandy/Misra Solution
1 for every pair of philosophers contending for a resource, create a fork and give it to the philosopher with
Lower ID. Each fork can either be dirty or clean. Initially, all forks are dirty.
2 when a philosopher wants to use a set of resources (I. e. Eat), he must obtain the forks from his contending
Neighbors. For all such forks he does not have, he sends a request message.
3 when a philosopher with a fork when es a request message, he keeps the fork if it is clean, but gives it up
When it is dirty. If he sends the fork over, he cleans the fork before doing so.
4 after a philosopher is done eating, all his forks become dirty. If another philosopher had previusly requested
One of the forks, he cleans the fork and sends it.
// The Flag status is constantly changing. A wonderful thing ..
Code:
Program D_p;
Const
Doomsday = false;
Monitor dining_philosophers; // initialize use of monitors
Const
Eating = 0;
Hungry = 1;
Thinking = 2;
VaR
I: integer; // init Loop Variable
State: array [0 .. 4] of integer; // eating, hungry, thinking
SELF: array [0 .. 4] of condition; // One for each philospher
// Place for hungry pH to wait until chopsticks become available
Procedure test (K: integer );
// If K's left & right neighbors aren't eating & K is hungry
// Then change K's state to eating & signalc (in case K is waitc-ing)
Begin
If (State [(k + 4) mod 5] <> eating) and (State [k] = hungry) and
(State [(k + 1) mod 5] <> eating) Then {right neighbor}
Begin
State [k]: = eating;
Signalc (Self [k]); // tell K to eat if K is waitc-ing
End;
End;
Procedure pickup (I: integer );
Begin
State [I]: = hungry;
Writeln ('losopher', I, 'hungry ');
Test (I); // are my neighbors eating?
If State [I] <> eating then // waitc if they are (sleep mode)
Waitc (Self [I]);
Writeln ('losopher ', I, 'eating ');
End;
Procedure putdown (I: integer );
Begin
State [I]: = thinking;
Writeln ('philower', I, 'thinking ');
Test (I + 4) mod 5); // give left neighbor chance to eat
Test (I + 1) mod 5); // give right neighbor chance to eat
End;
Begin // monitor Initialization
For I: = 0 to 4 do State [I]: = thinking;
End; // dining_philosopher Monitor
Procedure philosopher (I: integer );
Begin
Repeat
Pickup (I); // pick up chopsticks
Putdown (I); // put down chopsticks
Until doomsday;
End;
Begin
Cobegin // process to being all five processes at once
Philosopher (0); philosopher (1); philosopher (2 );
Philosopher (3); philosopher (4 );
Coend;
End