Presentation is loading. Please wait.

Presentation is loading. Please wait.

Slide 1 Concurrency, Dining Philosophers Lecture 14 COMP 201.

Similar presentations


Presentation on theme: "Slide 1 Concurrency, Dining Philosophers Lecture 14 COMP 201."— Presentation transcript:

1 Slide 1 Concurrency, Dining Philosophers Lecture 14 COMP 201

2 Slide 2 What is a Concurrent Program? A sequential program has a single thread of control. A concurrent program has multiple threads of control allowing it perform multiple computations in parallel and to control multiple external activities which occur at the same time.

3 Slide 3 Why Concurrent Programming? Performance gain from multiprocessing hardware –parallelism. Increased application throughput –an I/O call need only block one thread. Increased application responsiveness –high priority thread for user requests. More appropriate structure –for programs which interact with the environment, control multiple activities and handle multiple events.

4 Slide 4 Do I need to know about concurrent programming?  Therac - 25 computerised radiation therapy machine Concurrent programming errors contributed to accidents causing deaths and serious injuries.  Mars Rover Problems with interaction between concurrent tasks caused periodic software resets reducing availability for exploration. Concurrency is widespread but error prone.

5 Slide 5 Deadlock error

6 Slide 6 Deadlock Concepts : system deadlock: no further progress four necessary & sufficient conditions Models :deadlock - no eligible actions Practice : blocked threads Aim : deadlock avoidance - to design systems where deadlock cannot occur.

7 Slide 7 Deadlock: four necessary and sufficient conditions  Serially reusable resources: the processes involved share resources which they use under mutual exclusion.  Incremental acquisition: processes hold on to resources already allocated to them while waiting to acquire additional resources.  No pre-emption: once acquired by a process, resources cannot be pre-empted (forcibly withdrawn) but are only released voluntarily.  Wait-for cycle: a circular chain (or cycle) of processes exists such that each process holds a resource which its successor in the cycle is waiting to acquire.

8 Slide 8 Wait-for cycle A B C D E Has A awaits B Has B awaits C Has C awaits D Has D awaits E Has E awaits A

9 Slide 9 Dining Philosophers Five philosophers sit around a circular table. Each philosopher spends his life alternately thinking and eating. In the centre of the table is a large bowl of spaghetti. A philosopher needs two forks to eat a helping of spaghetti. 0 1 23 4 0 1 2 3 4 One fork is placed between each pair of philosophers and they agree that each will only use the fork to his immediate right and left.

10 Slide 10 Dining Philosophers - model structure diagram Each FORK is a shared resource with actions get and put. When hungry, each PHIL must first get his right and left forks before he can start eating.

11 Slide 11 Dining Philosophers

12 Slide 12 Dining Philosophers

13 Slide 13 ASML specification A number of philosophers are sitting around a table. Each one has a fork to the left and a fork to the right. We model forks as structures with a unique field index. structure Fork index as Integer

14 Slide 14 Abstract class Philosopher Philosophers are modelled as having a unique index, what state they are currently in and as being capable of two methods: –reporting whether they can make a state change (canMove) and –performing a state change (move). Because the value of the field status can change, a Philosopher is a class and not a structure. abstract class Philosopher var status as State = Thinking index as Integer canMove() as Boolean move()

15 Slide 15 For simplicity we assume that there are a fixed number (four) of true philosophers (called simply philosophers below) and one fake philosopher called nobody. numPhilosophers as Integer = 4 nobody as Philosopher = undef Likewise we have four forks. numForks as Integer = numPhilosophers forks as Set of Fork = { Fork(i) | i ∈ {1..numForks} } The fork to the left of a philosopher has the same index as the philosopher. The fork to the right of a philosopher has the next higher index (modulo the number of philosophers). left(p as Philosopher) as Fork return Fork(p.index) right(p as Philosopher) as Fork return Fork(p.index mod numPhilosophers + 1)

16 Slide 16 Philosopher’s lifecycle A thinking philosopher has no forks. (Who needs a fork to think?) A thinking philosopher may become hungry. A hungry philosopher tries to grab the fork to the left and thus becomes a hungry philosopher with a left fork. But one fork is not enough: a philosopher starts eating only upon obtaining both forks. The fork to right can be obtained only if it is not being used. From eating, there is only one place to go: back to thinking after putting down both forks.

17 Slide 17 A successful philosopher's lifecycle is this Thinking Hungry HungryWithLeftForkEating enum State Thinking; Hungry; HungryWithLeftFork; Eating Initially nobody has a fork. var holder as Map of Fork to Philosopher = { f ↦ nobody | f ∈ forks }

18 Slide 18 Greedy Philosophers A greedy philosopher never puts down a fork until (s)he has eaten and starts thinking. This can lead to deadlock. The behaviour has been made a little fancier by introducing a random amount of thinking and eating for a fixed amount of time –a thinking philosopher will remain thinking about 80 percent of the time.

19 Slide 19 class greedyPhilosopher extends Philosopher var bites as Integer = 0 move() match status Thinking : if (any i | i ∈ {1..10}) 0 then bites := bites - 1 else holder(left(me)) := nobody holder(right(me)) := nobody status := Thinking

20 Slide 20 Extracting the conditions from the method move yields the function canMove which indicates whether the philosopher can make a state change or not. class greedyPhilosopher... canMove() as Boolean return status = Thinking ∨ (status = Hungry ∧ holder(left(me)) = nobody) ∨ (status = HungryWithLeftFork ∧ holder(right(me)) = nobody) ∨ status = Eating asString() as String return "Greedy #" + index

21 Slide 21 Generous Philosophers A generous philosopher does not insist on following a successful philosophical life. After picking up the left fork, but finding that the right fork is not available, a generous philosopher drops the left fork and goes back to think some more. So if all philosophers are generous, then there is no deadlock, but starvation is possible.

22 Slide 22 class generousPhilosopher extends Philosopher move() match status Thinking : status := Hungry Hungry : if holder(left(me)) = nobody then holder(left(me)) := me status := HungryWithLeftFork HungryWithLeftFork : if holder(right(me)) = nobody then holder(right(me)) := me status := Eating else // someone else is holding the right fork put // the left one down and try again another time holder(left(me)) := nobody status := Thinking Eating : holder(left(me)) := nobody holder(right(me)) := nobody status := Thinking

23 Slide 23 Notice that the conditions which indicate whether a generous philosopher can make a state change or not are more liberal than those for greedy philosophers. class generousPhilosopher... canMove() as Boolean return status = Thinking ∨ (status = Hungry ∧ holder(left(me)) = nobody) ∨ status = HungryWithLeftFork ∨ status = Eating asString() as String return "Generous #" + index

24 Slide 24 A successful generous philosopher's lifecycle is this Thinking Hungry HungryWithLeftForkEating

25 Slide 25 The Scheduler Here is one possible scheduler: –From the set that it is given, it chooses a philosopher that can make a state transition and then fires the state transition. –If no philosopher can make a step, then the system is deadlocked and an exception is thrown.

26 Slide 26 structure deadlockException implements RuntimeException message as String describe() as String return "Deadlock: " + message schedule(ps as Set of Philosopher, i as Integer) choose p ∈ ps where p.canMove() step currentStatus = p.status p.move() step WriteLine(p + " was " + currentStatus + ", but now is " + p.status) ifnone throw deadlockException("after " + i + " steps")

27 Slide 27 The Main Program The main program tries to run the above schedule 1000 times, and is ready to catch the exception thrown if the system deadlocks. You may choose which type of philosopher to schedule, just comment out one of the "greedy" or "generous" lines in the code.

28 Slide 28 Main() phils = { new greedyPhilosopher(i) as Philosopher | i ∈ [1..numPhilosophers] } //phils = { new generousPhilosopher(i) as Philosopher | i ∈ [1..numPhilosophers] } try step foreach i ∈ [1..1000] schedule( phils, i ) catch d as deadlockException : WriteLine(d.describe()) The Main Program (code)

29 Slide 29 Summary Concepts –deadlock: no futher progress –four necessary and sufficient conditions: serially reusable resources incremental acquisition no preemption wait-for cycle Models –no eligable actions (analysis gives shortest path trace) Practice –blocked threads Aim: deadlock avoidance - to design systems where deadlock cannot occur.


Download ppt "Slide 1 Concurrency, Dining Philosophers Lecture 14 COMP 201."

Similar presentations


Ads by Google